--- /dev/null
+obj-arm-linux-gnueabi
+.cproject
+.project
+debian/files
+debian/*.debhelper.log
+debian/smartcard-service-common-dbg/
+debian/smartcard-service-common-dev/
+debian/smartcard-service-common/
+debian/smartcard-service-dbg/
+debian/smartcard-service-dev/
+debian/smartcard-service-server-dbg/
+debian/smartcard-service-server/
+debian/*.debhelper
+debian/*.substvars
+debian/smartcard-service/
+debian/tmp/
+gbs_temp
SET(CMAKE_VERBOSE_MAKEFILE OFF)
-IF("${USE_AUTOSTART}" STREQUAL "1")
+# apply smack
+ADD_DEFINITIONS("-DUSER_SPACE_SMACK")
+
+IF(DEFINED USE_AUTOSTART)
ADD_DEFINITIONS("-DUSE_AUTOSTART")
ENDIF()
-ADD_DEFINITIONS("-DCLIENT_IPC_THREAD")
-ADD_DEFINITIONS("-DUSE_IPC_EPOLL")
+# make string from entire content of byte array
+ADD_DEFINITIONS("-DTO_STRING_ALL")
+
+SET(GC_SECTIONS_FLAGS "-fdata-sections -ffunction-sections -Wl,--gc-sections")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GC_SECTIONS_FLAGS}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GC_SECTIONS_FLAGS}")
+
+FIND_PROGRAM(GDBUS_CODEGEN NAMES gdbus-codegen)
+EXEC_PROGRAM(${GDBUS_CODEGEN} ARGS
+ " \\
+ --generate-c-code ${CMAKE_CURRENT_SOURCE_DIR}/common/smartcard-service-gdbus \\
+ --c-namespace SmartcardService\\
+ --interface-prefix org.tizen.SmartcardService. \\
+ ${CMAKE_CURRENT_SOURCE_DIR}/common/smartcard-service-gdbus.xml \\
+ ")
ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(client)
ADD_SUBDIRECTORY(server)
-ADD_SUBDIRECTORY(test-client)
+
+IF(DEFINED TEST_CLIENT)
+ ADD_SUBDIRECTORY(test-client)
+ENDIF()
SET(VERSION_MAJOR 1)
SET(VERSION ${VERSION_MAJOR}.0.0)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../server/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")
+ SET(CMAKE_BUILD_TYPE "Release")
ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+# pkg config
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs_client REQUIRED gthread-2.0 dlog dbus-glib-1 security-server)
+
+SET(PKG_MODULE glib-2.0 dlog)
+
+pkg_check_modules(pkgs_client REQUIRED ${PKG_MODULE})
MESSAGE("${LIB_NAME} ld flag : ${pkgs_client_LDFLAGS}")
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 "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -finstrument-functions")
#SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
#SET(CMAKE_C_FLAGS_RELEASE "-O2")
-#SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -finstrument-functions -std=c++0x")
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -finstrument-functions -std=c++0x")
#SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
#SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
FOREACH(hfile ${EXPORT_HEADER})
- INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
+ INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
ENDFOREACH(hfile)
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <glib.h>
/* SLP library header */
/* local header */
#include "Debug.h"
-#include "Message.h"
-#include "ClientIPC.h"
#include "ClientChannel.h"
#include "ReaderHelper.h"
#include "APDUHelper.h"
+#include "ClientGDBus.h"
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
namespace smartcard_service_api
{
ClientChannel::ClientChannel(void *context, Session *session,
- int channelNum, ByteArray selectResponse, void *handle)
+ int channelNum, const ByteArray &selectResponse, void *handle)
: Channel(session)
{
this->channelNum = -1;
if (handle == NULL)
{
- SCARD_DEBUG_ERR("ClientIPC::getInstance() failed");
+ _ERR("ClientIPC::getInstance() failed");
return;
}
this->handle = handle;
this->selectResponse = selectResponse;
this->context = context;
+
+ /* init default context */
+ GError *error = NULL;
+
+ proxy = smartcard_service_channel_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/Channel",
+ NULL, &error);
+ if (proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return;
+ }
}
ClientChannel::~ClientChannel()
closeSync();
}
+ void ClientChannel::channel_transmit_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ transmitCallback callback;
+ gint result;
+ GVariant *var_response;
+ GError *error = NULL;
+ ByteArray response;
+
+ _INFO("MSG_REQUEST_TRANSMIT");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ callback = (transmitCallback)param->callback;
+
+ if (smartcard_service_channel_call_transmit_finish(
+ SMARTCARD_SERVICE_CHANNEL(source_object),
+ &result, &var_response, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ GDBusHelper::convertVariantToByteArray(var_response, response);
+ } else {
+ _ERR("smartcard_service_channel_call_transmit failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_channel_call_transmit failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(response.getBuffer(),
+ response.size(),
+ result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ void ClientChannel::channel_close_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ ClientChannel *channel;
+ closeChannelCallback callback;
+ gint result;
+ GError *error = NULL;
+
+ _INFO("MSG_REQUEST_CLOSE_CHANNEL");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ channel = (ClientChannel *)param->instance;
+ callback = (closeChannelCallback)param->callback;
+
+ if (smartcard_service_channel_call_close_channel_finish(
+ SMARTCARD_SERVICE_CHANNEL(source_object),
+ &result, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ channel->channelNum = -1;
+ } else {
+ _ERR("smartcard_service_channel_call_close_channel failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_channel_call_close_channel failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(result, param->user_param);
+ }
+
+ delete param;
+ }
+
void ClientChannel::closeSync()
throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &)
{
-#ifdef CLIENT_IPC_THREAD
if (isClosed() == false)
{
if (getSession()->getReader()->isSecureElementPresent() == true)
{
- Message msg;
- int rv;
-
- /* send message to server */
- msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
-
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- rv = waitTimedCondition(0);
- if (rv < 0)
- {
- SCARD_DEBUG_ERR("closeSync failed [%d]", rv);
- this->error = SCARD_ERROR_OPERATION_TIMEOUT;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- this->error = SCARD_ERROR_IPC_FAILED;
+ gint ret;
+ GError *error = NULL;
+
+
+ if (proxy == NULL) {
+ _ERR("dbus proxy is not initialized yet");
+ throw ErrorIllegalState(SCARD_ERROR_NOT_INITIALIZED);
}
- syncUnlock();
- channelNum = -1;
+ if (smartcard_service_channel_call_close_channel_sync(
+ (SmartcardServiceChannel *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ &ret, NULL, &error) == true) {
+ if (ret == SCARD_ERROR_OK) {
+ channelNum = -1;
+ } else {
+ _ERR("smartcard_service_channel_call_close_channel_sync failed, [%d]", ret);
+ THROW_ERROR(ret);
+ }
+ } else {
+ _ERR("smartcard_service_channel_call_close_channel_sync failed, [%s]", error->message);
+ g_error_free(error);
- if (this->error != SCARD_ERROR_OK)
- {
- ThrowError::throwError(this->error);
+ throw ErrorIO(SCARD_ERROR_IPC_FAILED);
}
}
else
{
- /* FIXME */
- SCARD_DEBUG("unavailable channel");
+ _INFO("unavailable channel");
}
}
-#endif
}
- int ClientChannel::close(closeCallback callback, void *userParam)
+ int ClientChannel::close(closeChannelCallback callback, void *userParam)
{
int result = SCARD_ERROR_OK;
{
if (getSession()->getReader()->isSecureElementPresent() == true)
{
- Message msg;
- channelNum = -1;
-
- /* send message to server */
- msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)callback;
- msg.userParam = userParam;
-
- if (ClientIPC::getInstance().sendMessage(&msg) == false)
- {
- result = SCARD_ERROR_IPC_FAILED;
- }
+ CallbackParam *param = new CallbackParam();
+
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userParam;
+
+ smartcard_service_channel_call_close_channel(
+ (SmartcardServiceChannel *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle), NULL,
+ &ClientChannel::channel_close_cb, param);
}
else
{
- SCARD_DEBUG_ERR("unavailable channel");
+ _ERR("unavailable channel");
result = SCARD_ERROR_ILLEGAL_STATE;
}
}
return result;
}
- int ClientChannel::transmitSync(ByteArray command, ByteArray &result)
+ int ClientChannel::transmitSync(const ByteArray &command, ByteArray &result)
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &)
{
if (getSession()->getReader()->isSecureElementPresent() == true)
{
- Message msg;
-
-#ifdef CLIENT_IPC_THREAD
- /* send message to server */
- msg.message = Message::MSG_REQUEST_TRANSMIT;
- msg.param1 = (unsigned long)handle;
- msg.param2 = 0;
- msg.data = command;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
-
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- rv = waitTimedCondition(0);
- if (rv >= 0)
- {
- result = response;
-
- rv = SCARD_ERROR_OK;
+ GVariant *var_command = NULL, *var_response = NULL;
+ GError *error = NULL;
+
+ var_command = GDBusHelper::convertByteArrayToVariant(command);
+
+ if (smartcard_service_channel_call_transmit_sync(
+ (SmartcardServiceChannel *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ var_command, &rv, &var_response,
+ NULL, &error) == true) {
+
+ if (rv == SCARD_ERROR_OK) {
+ GDBusHelper::convertVariantToByteArray(var_response, transmitResponse);
+ result = transmitResponse;
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", rv);
+ THROW_ERROR(rv);
}
- else
- {
- SCARD_DEBUG_ERR("timeout");
-
- this->error = SCARD_ERROR_OPERATION_TIMEOUT;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- }
- syncUnlock();
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
+ g_error_free(error);
- if (this->error != SCARD_ERROR_OK)
- {
- ThrowError::throwError(this->error);
+ throw ErrorIO(SCARD_ERROR_IPC_FAILED);
}
-#endif
}
else
{
- SCARD_DEBUG_ERR("unavailable channel");
+ _ERR("unavailable channel");
throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
}
return rv;
}
- int ClientChannel::transmit(ByteArray command, transmitCallback callback, void *userParam)
+ int ClientChannel::transmit(const ByteArray &command, transmitCallback callback, void *userParam)
{
int result;
if (getSession()->getReader()->isSecureElementPresent() == true)
{
- Message msg;
-
- /* send message to server */
- msg.message = Message::MSG_REQUEST_TRANSMIT;
- msg.param1 = (unsigned long)handle;
- msg.param2 = 0;
- msg.data = command;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)callback;
- msg.userParam = userParam;
-
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- result = SCARD_ERROR_OK;
- }
- else
- {
- result = SCARD_ERROR_IPC_FAILED;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("unavailable channel");
- result = SCARD_ERROR_ILLEGAL_STATE;
- }
+ GVariant *var_command;
+ CallbackParam *param = new CallbackParam();
- return result;
- }
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userParam;
- bool ClientChannel::dispatcherCallback(void *message)
- {
- Message *msg = (Message *)message;
- ClientChannel *channel = NULL;
- bool result = false;
+ var_command = GDBusHelper::convertByteArrayToVariant(command);
- if (msg == NULL)
- {
- SCARD_DEBUG_ERR("message is null");
- return result;
- }
-
- channel = (ClientChannel *)msg->caller;
+ smartcard_service_channel_call_transmit(
+ (SmartcardServiceChannel *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ var_command, NULL,
+ &ClientChannel::channel_transmit_cb, param);
- switch (msg->message)
+ result = SCARD_ERROR_OK;
+ }
+ else
{
- case Message::MSG_REQUEST_TRANSMIT :
- {
- /* transmit result */
- SCARD_DEBUG("MSG_REQUEST_TRANSMIT");
-
- if (msg->error == 0 &&
- ResponseHelper::getStatus(msg->data) == 0)
- {
- /* store select response */
- if (msg->data.getAt(1) == APDUCommand::INS_SELECT_FILE)
- channel->setSelectResponse(msg->data);
- }
-
- if (msg->isSynchronousCall() == true) /* 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->isSynchronousCall() == true) /* 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;
+ _ERR("unavailable channel");
+ result = SCARD_ERROR_ILLEGAL_STATE;
}
return result;
} \
else \
{ \
- SCARD_DEBUG_ERR("Invalid param"); \
+ _ERR("Invalid param"); \
}
using namespace smartcard_service_api;
-EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
+EXTERN_API int channel_close_sync(channel_h handle)
{
- int result = -1;
+ int result = SCARD_ERROR_OK;
CHANNEL_EXTERN_BEGIN;
- result = channel->close((closeCallback)callback, userParam);
+
+ try
+ {
+ channel->closeSync();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
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)
+EXTERN_API int channel_transmit_sync(channel_h handle, unsigned char *command,
+ unsigned int cmd_len, unsigned char **response, unsigned int *resp_len)
{
- int result = -1;
+ int result = SCARD_ERROR_OK;
+
+ if (command == NULL || cmd_len == 0 || response == NULL || resp_len == NULL)
+ return SCARD_ERROR_UNKNOWN;
CHANNEL_EXTERN_BEGIN;
- ByteArray temp;
- temp.setBuffer(command, length);
- result = channel->transmit(temp, (transmitCallback)callback, userParam);
+ try
+ {
+ ByteArray temp, resp;
+
+ temp.assign(command, cmd_len);
+ channel->transmitSync(temp, resp);
+
+ if (resp.size() > 0)
+ {
+ *resp_len = resp.size();
+ memcpy(*response, resp.getBuffer(), *resp_len);
+ }
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *resp_len = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *resp_len = 0;
+ }
+
CHANNEL_EXTERN_END;
return result;
}
-EXTERN_API void channel_close_sync(channel_h handle)
+EXTERN_API int channel_is_basic_channel(channel_h handle, bool* is_basic_channel)
{
-#ifdef CLIENT_IPC_THREAD
+ int result = SCARD_ERROR_OK;
+
CHANNEL_EXTERN_BEGIN;
+
try
{
- channel->closeSync();
+ *is_basic_channel = channel->isBasicChannel();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
}
catch (...)
{
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
}
+
CHANNEL_EXTERN_END;
-#endif
+
+ return result;
}
-EXTERN_API int channel_transmit_sync(channel_h handle, unsigned char *command,
- unsigned int cmd_len, unsigned char **response, unsigned int *resp_len)
+EXTERN_API int channel_is_closed(channel_h handle, bool* is_closed)
{
- int result = -1;
+ int result = SCARD_ERROR_OK;
-#ifdef CLIENT_IPC_THREAD
- if (command == NULL || cmd_len == 0 || response == NULL || resp_len == NULL)
- return result;
+ CHANNEL_EXTERN_BEGIN;
+
+ try
+ {
+ *is_closed = channel->isClosed();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_get_select_response(channel_h handle,
+ unsigned char *buffer, size_t *length)
+{
+ int result = SCARD_ERROR_OK;
CHANNEL_EXTERN_BEGIN;
- ByteArray temp, resp;
- temp.setBuffer(command, cmd_len);
+ try
+ {
+ ByteArray response = channel->getSelectResponse();
+
+ *length = MIN(*length, response.size());
+
+ if (*length > 0)
+ {
+ memcpy(buffer, response.getBuffer(), *length);
+ }
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *length = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *length = 0;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_get_transmit_response(channel_h handle,
+ unsigned char *buffer, size_t *length)
+{
+ int result = SCARD_ERROR_OK;
+
+ CHANNEL_EXTERN_BEGIN;
try
{
- result = channel->transmitSync(temp, resp);
- if (resp.getLength() > 0)
+ ByteArray response;
+
+ response = channel->getTransmitResponse();
+
+ *length = MIN(*length, response.size());
+
+ if (*length > 0)
{
- *resp_len = resp.getLength();
- *response = (unsigned char *)calloc(1, *resp_len);
- memcpy(*response, resp.getBuffer(), *resp_len);
+ memcpy(buffer, response.getBuffer(), *length);
}
}
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *length = 0;
+ }
catch (...)
{
- result = -1;
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *length = 0;
}
+
CHANNEL_EXTERN_END;
-#endif
return result;
}
-EXTERN_API bool channel_is_basic_channel(channel_h handle)
+EXTERN_API int channel_get_session(channel_h handle, int *session_handle)
{
- bool result = false;
+ int result = SCARD_ERROR_OK;
+ session_h session = NULL;
CHANNEL_EXTERN_BEGIN;
- result = channel->isBasicChannel();
+
+ try
+ {
+ session = channel->getSession();
+ *session_handle = (int)session;
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
CHANNEL_EXTERN_END;
return result;
}
-EXTERN_API bool channel_is_closed(channel_h handle)
+EXTERN_API int channel_select_next(channel_h handle, bool *pSuccess)
{
- bool result = false;
+ int result = SCARD_ERROR_OK;
CHANNEL_EXTERN_BEGIN;
- result = channel->isClosed();
+
+ try
+ {
+ *pSuccess = channel->selectNext();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
CHANNEL_EXTERN_END;
return result;
unsigned int result = 0;
CHANNEL_EXTERN_BEGIN;
- result = channel->getSelectResponse().getLength();
+ result = channel->getSelectResponse().size();
CHANNEL_EXTERN_END;
return result;
}
-EXTERN_API bool channel_get_select_response(channel_h handle,
- unsigned char *buffer, unsigned int length)
+EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
{
- bool result = false;
-
- if (buffer == NULL || length == 0)
- {
- return result;
- }
+ int result = -1;
CHANNEL_EXTERN_BEGIN;
- ByteArray response;
-
- response = channel->getSelectResponse();
- if (response.getLength() > 0)
- {
- memcpy(buffer, response.getBuffer(), MIN(length, response.getLength()));
- result = true;
- }
+ result = channel->close((closeChannelCallback)callback, userParam);
CHANNEL_EXTERN_END;
return result;
}
-EXTERN_API session_h channel_get_session(channel_h handle)
+EXTERN_API int channel_transmit(channel_h handle, unsigned char *command,
+ unsigned int length, channel_transmit_cb callback, void *userParam)
{
- session_h session = NULL;
+ int result = -1;
CHANNEL_EXTERN_BEGIN;
- session = channel->getSession();
+ ByteArray temp;
+
+ temp.assign(command, length);
+ result = channel->transmit(temp, (transmitCallback)callback, userParam);
CHANNEL_EXTERN_END;
- return session;
+ return result;
}
EXTERN_API void channel_destroy_instance(channel_h handle)
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* standard library header */
-#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 :
- case Message::MSG_REQUEST_SHUTDOWN :
- {
- if (msg->isSynchronousCall() == false)
- {
- DispatcherMsg *tempMsg = new DispatcherMsg(msg);
-
- /* Asynchronous call */
- g_idle_add((GSourceFunc)&SEService::dispatcherCallback, (gpointer)tempMsg);
- }
- else
- {
- /* Synchronous call */
- SEService::dispatcherCallback(msg);
- }
- }
- break;
-
- /* Reader requests */
- case Message::MSG_REQUEST_OPEN_SESSION :
- {
- if (msg->isSynchronousCall() == false)
- {
- DispatcherMsg *tempMsg = new DispatcherMsg(msg);
-
- /* Asynchronous call */
- g_idle_add((GSourceFunc)&Reader::dispatcherCallback, (gpointer)tempMsg);
- }
- else
- {
- /* Synchronous call */
- Reader::dispatcherCallback(msg);
- }
- }
- 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 :
- {
- if (msg->isSynchronousCall() == false)
- {
- DispatcherMsg *tempMsg = new DispatcherMsg(msg);
-
- /* Asynchronous call */
- g_idle_add((GSourceFunc)&Session::dispatcherCallback, (gpointer)tempMsg);
- }
- else
- {
- /* Synchronous call */
- Session::dispatcherCallback(msg);
- }
- }
- break;
-
- /* ClientChannel requests */
- case Message::MSG_REQUEST_TRANSMIT :
- case Message::MSG_REQUEST_CLOSE_CHANNEL :
- {
- if (msg->isSynchronousCall() == false)
- {
- DispatcherMsg *tempMsg = new DispatcherMsg(msg);
-
- /* Asynchronous call */
- g_idle_add((GSourceFunc)&ClientChannel::dispatcherCallback, (gpointer)tempMsg);
- }
- else
- {
- /* Synchronous call */
- ClientChannel::dispatcherCallback(msg);
- }
- }
- 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;
-
- /* Always asynchronous call */
- 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;
-
- /* Always asynchronous call */
- g_idle_add((GSourceFunc)&SEService::dispatcherCallback, (gpointer)tempMsg);
- }
- }
- break;
-
- default :
- break;
- }
-
- SCARD_END();
-
- return NULL;
- }
-
-} /* namespace open_mobile_api */
-
*/
/* standard library header */
+#include <glib.h>
/* SLP library header */
/* local header */
+#include "smartcard-types.h"
#include "Debug.h"
-#include "ProviderHelper.h"
+#include "ByteArray.h"
+#include "ClientGDBus.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;
- }
+using namespace std;
- ProviderHelper::~ProviderHelper()
- {
- }
+/* below functions will be called when dlopen or dlclose is called */
+void __attribute__ ((constructor)) lib_init()
+{
+ g_type_init();
+}
- Channel *ProviderHelper::getChannel()
- {
- return channel;
- }
+void __attribute__ ((destructor)) lib_fini()
+{
+}
+namespace smartcard_service_api
+{
} /* namespace smartcard_service_api */
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* standard library header */
-#include <sys/socket.h>
-#include <unistd.h>
-
-/* SLP library header */
-#ifdef SECURITY_SERVER
-#include "security-server.h"
-#endif
-
-/* local header */
-#include "Debug.h"
-#include "ClientIPC.h"
-#include "DispatcherMsg.h"
-
-namespace smartcard_service_api
-{
- ClientIPC::ClientIPC():IPCHelper()
- {
-#ifdef USE_AUTOSTART
- _launch_daemon();
-#endif
-#ifdef SECURITY_SERVER
- int length;
-
- if ((length = security_server_get_cookie_size()) > 0)
- {
- uint8_t *buffer = NULL;
-
- buffer = new uint8_t[length];
- if (buffer != NULL)
- {
- int error;
-
- if ((error = security_server_request_cookie(buffer, length))
- == SECURITY_SERVER_API_SUCCESS)
- {
- cookie.setBuffer(buffer, length);
-
- SCARD_DEBUG("cookie : %s", cookie.toString());
- }
- else
- {
- SCARD_DEBUG_ERR("security_server_request_cookie failed [%d]", error);
- }
-
- delete []buffer;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("security_server_get_cookie_size failed");
- }
-#endif
- }
-
- ClientIPC::~ClientIPC()
- {
- }
-
- ClientIPC &ClientIPC::getInstance()
- {
- static ClientIPC clientIPC;
-
- return clientIPC;
- }
-
-#ifdef USE_AUTOSTART
- void ClientIPC::_launch_daemon()
- {
- DBusGConnection *connection;
- GError *error = NULL;
-
- SCARD_BEGIN();
-
- dbus_g_thread_init();
-
- g_type_init();
-
- connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
- if (error == NULL)
- {
- DBusGProxy *proxy;
-
- proxy = dbus_g_proxy_new_for_name(connection, "org.tizen.smartcard_service",
- "/org/tizen/smartcard_service", "org.tizen.smartcard_service");
- if (proxy != NULL)
- {
- gint result = 0;
-
- if (dbus_g_proxy_call(proxy, "launch", &error, G_TYPE_INVALID,
- G_TYPE_INT, &result, G_TYPE_INVALID) == false)
- {
- SCARD_DEBUG_ERR("org_tizen_smartcard_service_launch failed");
- if (error != NULL)
- {
- SCARD_DEBUG_ERR("message : [%s]", error->message);
- g_error_free(error);
- }
- }
- }
- else
- {
- SCARD_DEBUG_ERR("ERROR: Can't make dbus proxy");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("ERROR: Can't get on system bus [%s]", error->message);
- g_error_free(error);
- }
-
- SCARD_END();
- }
-#endif
-
- bool ClientIPC::sendMessage(Message *msg)
- {
- ByteArray stream;
- unsigned int length;
-
- if (ipcSocket == -1)
- return false;
-
-#ifdef SECURITY_SERVER
- stream = cookie + msg->serialize();
-#else
- stream = msg->serialize();
-#endif
- length = stream.getLength();
-
- SCARD_DEBUG(">>>[SEND]>>> socket [%d], msg [%d], length [%d]",
- ipcSocket, msg->message, stream.getLength());
-
- return IPCHelper::sendMessage(ipcSocket, stream);
- }
-
- int ClientIPC::handleIOErrorCondition(void *channel, GIOCondition condition)
- {
- SCARD_BEGIN();
-
- if (dispatcher != NULL)
- {
- DispatcherMsg dispMsg;
-
- /* push or process disconnect message */
- dispMsg.message = Message::MSG_OPERATION_RELEASE_CLIENT;
- dispMsg.error = -1;
-
-#ifdef CLIENT_IPC_THREAD
- dispatcher->processMessage(&dispMsg);
-#else
- dispatcher->pushMessage(&dispMsg);
-#endif
- }
-
- SCARD_END();
-
- return FALSE;
- }
-
- int ClientIPC::handleInvalidSocketCondition(void *channel, GIOCondition condition)
- {
- SCARD_BEGIN();
-
- /* finalize context */
- destroyConnectSocket();
-
- SCARD_END();
-
- return FALSE;
- }
-
- int ClientIPC::handleIncomingCondition(void *channel, GIOCondition condition)
- {
- int result = FALSE;
-
- SCARD_BEGIN();
-
-#ifndef CLIENT_IPC_THREAD
- if (channel == ioChannel)
- {
-#endif
- Message *msg = NULL;
-
- SCARD_DEBUG("message from server to client socket");
-
- /* read message */
- msg = retrieveMessage();
- if (msg != NULL)
- {
- DispatcherMsg dispMsg(msg);
-
- /* set peer socket */
- dispMsg.setPeerSocket(ipcSocket);
-
- /* push to dispatcher */
- if (dispatcher != NULL)
- {
-#ifdef CLIENT_IPC_THREAD
- dispatcher->processMessage(&dispMsg);
-#else
- dispatcher->pushMessage(&dispMsg);
-#endif
- }
-
- delete msg;
- }
- else
- {
- /* clear client connection */
-#ifdef CLIENT_IPC_THREAD
- handleIOErrorCondition(channel, condition);
- result = -1;
-#endif
- }
-
-#ifndef CLIENT_IPC_THREAD
- }
- else
- {
- SCARD_DEBUG_ERR("Unknown channel event [%p]", channel);
- }
-#endif
-
- SCARD_END();
-
- return result;
- }
-
-} /* namespace open_mobile_api */
/* local header */
#include "Debug.h"
-#include "Message.h"
-#include "ClientIPC.h"
#include "Reader.h"
#include "Session.h"
+#include "ClientGDBus.h"
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
namespace smartcard_service_api
{
- Reader::Reader(void *context, const char *name, void *handle)
- : ReaderHelper()
+ Reader::Reader(void *context, const char *name, void *handle) :
+ ReaderHelper(name), context(context), handle(handle)
{
- unsigned int length = 0;
+ _BEGIN();
- SCARD_BEGIN();
-
- this->context = NULL;
- this->handle = NULL;
-
- if (context == NULL || name == NULL || strlen(name) == 0 || handle == NULL)
+ if (context == NULL || handle == NULL)
{
- SCARD_DEBUG_ERR("invalid param");
+ _ERR("invalid param");
return;
}
- this->handle = handle;
- this->context = context;
+ /* init default context */
+ GError *error = NULL;
- length = strlen(name);
- length = (length < sizeof(this->name)) ? length : sizeof(this->name);
- memcpy(this->name, name, length);
+ proxy = smartcard_service_reader_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/Reader",
+ NULL, &error);
+ if (proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return;
+ }
present = true;
- SCARD_END();
+ _END();
}
Reader::~Reader()
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &)
{
- openedSession = NULL;
+ Session *session = NULL;
if (isSecureElementPresent() == true)
{
- Message msg;
- int rv;
-
-#ifdef CLIENT_IPC_THREAD
- /* request channel handle from server */
- msg.message = Message::MSG_REQUEST_OPEN_SESSION;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
-
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- rv = waitTimedCondition(0);
- if (rv != 0)
- {
- SCARD_DEBUG_ERR("time over");
- this->error = SCARD_ERROR_OPERATION_TIMEOUT;
+ gint result;
+ GError *error = NULL;
+ guint session_id;
+
+ if (smartcard_service_reader_call_open_session_sync(
+ (SmartcardServiceReader *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ &result, &session_id, NULL, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ /* create new instance of channel */
+ session = new Session(context, this,
+ GUINT_TO_POINTER(session_id));
+ if (session != NULL) {
+ sessions.push_back(session);
+ } else {
+ _ERR("Session creating instance failed");
+
+ THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
+ }
+ } else {
+ _ERR("smartcard_service_reader_call_open_session_sync failed, [%d]", result);
+
+ THROW_ERROR(result);
}
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- this->error = SCARD_ERROR_IPC_FAILED;
- }
- syncUnlock();
+ } else {
+ _ERR("smartcard_service_reader_call_open_session_sync failed, [%s]", error->message);
+ g_error_free(error);
- if (this->error != SCARD_ERROR_OK)
- {
- ThrowError::throwError(this->error);
+ THROW_ERROR(SCARD_ERROR_IPC_FAILED);
}
-#endif
}
else
{
- SCARD_DEBUG_ERR("unavailable reader");
+ _ERR("unavailable reader");
throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
}
- return (Session *)openedSession;
+ return session;
}
- int Reader::openSession(openSessionCallback callback, void *userData)
+ void Reader::reader_open_session_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
{
- int result;
-
- SCARD_BEGIN();
-
- if (isSecureElementPresent() == true)
- {
- Message msg;
-
- /* request channel handle from server */
- msg.message = Message::MSG_REQUEST_OPEN_SESSION;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)callback;
- msg.userParam = userData;
-
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- result = SCARD_ERROR_OK;
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- result = SCARD_ERROR_IPC_FAILED;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("unavailable reader");
- result = SCARD_ERROR_ILLEGAL_STATE;
- }
-
- SCARD_END();
-
- return result;
- }
-
- bool Reader::dispatcherCallback(void *message)
- {
- Message *msg = (Message *)message;
+ CallbackParam *param = (CallbackParam *)user_data;
Reader *reader;
- bool result = false;
+ openSessionCallback callback;
+ Session *session = NULL;
+ gint result;
+ guint handle;
+ GError *error = NULL;
- SCARD_BEGIN();
+ _INFO("MSG_REQUEST_OPEN_SESSION");
- if (msg == NULL)
- {
- SCARD_DEBUG_ERR("message is null");
- return result;
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
}
- reader = (Reader *)msg->caller;
-
- switch (msg->message)
- {
- case Message::MSG_REQUEST_OPEN_SESSION :
- {
- Session *session = NULL;
+ reader = (Reader *)param->instance;
+ callback = (openSessionCallback)param->callback;
+
+ if (smartcard_service_reader_call_open_session_finish(
+ SMARTCARD_SERVICE_READER(source_object),
+ &result, &handle, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ /* create new instance of channel */
+ session = new Session(reader->context, reader,
+ GUINT_TO_POINTER(handle));
+ if (session != NULL) {
+ reader->sessions.push_back(session);
+ } else {
+ _ERR("Session creating instance failed");
- SCARD_DEBUG("MSG_REQUEST_OPEN_SESSION");
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ _ERR("smartcard_service_reader_call_open_session failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_reader_call_open_session failed, [%s]", error->message);
+ g_error_free(error);
- 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");
+ result = SCARD_ERROR_IPC_FAILED;
+ }
- return session;
- }
+ if (callback != NULL) {
+ callback(session, result, param->user_param);
+ }
- reader->sessions.push_back(session);
- }
+ delete param;
+ }
+ int Reader::openSession(openSessionCallback callback, void *userData)
+ {
+ int result;
- if (msg->isSynchronousCall() == true) /* synchronized call */
- {
- /* sync call */
- reader->syncLock();
+ _BEGIN();
- /* copy result */
- reader->error = msg->error;
- reader->openedSession = session;
- reader->signalCondition();
+ if (isSecureElementPresent() == true)
+ {
+ CallbackParam *param = new CallbackParam();
- reader->syncUnlock();
- }
- else if (msg->callback != NULL)
- {
- openSessionCallback cb = (openSessionCallback)msg->callback;
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userData;
- /* async call */
- cb(session, msg->error, msg->userParam);
- }
- }
- break;
+ smartcard_service_reader_call_open_session(
+ (SmartcardServiceReader *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ NULL, &Reader::reader_open_session_cb, param);
- default:
- SCARD_DEBUG("unknown [%s]", msg->toString());
- break;
+ result = SCARD_ERROR_OK;
+ }
+ else
+ {
+ _ERR("unavailable reader");
+ result = SCARD_ERROR_ILLEGAL_STATE;
}
- SCARD_END();
+ _END();
return result;
}
-
} /* namespace smartcard_service_api */
/* export C API */
} \
else \
{ \
- SCARD_DEBUG_ERR("Invalid param"); \
+ _ERR("Invalid param"); \
}
using namespace smartcard_service_api;
-EXTERN_API const char *reader_get_name(reader_h handle)
+EXTERN_API int reader_get_name(reader_h handle, char** reader_name)
{
+ int result = SCARD_ERROR_OK;
const char *name = NULL;
READER_EXTERN_BEGIN;
- name = reader->getName();
+
+ try
+ {
+ name = reader->getName();
+
+ *reader_name = (char*)calloc(strlen(name), sizeof(char));
+ strcpy(*reader_name, name);
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
READER_EXTERN_END;
- return name;
+ return result;
}
-EXTERN_API se_service_h reader_get_se_service(reader_h handle)
+EXTERN_API int reader_is_secure_element_present(reader_h handle, bool* is_present)
{
- se_service_h service = NULL;
+ int result = SCARD_ERROR_OK;
READER_EXTERN_BEGIN;
- service = (se_service_h)reader->getSEService();
+
+ try
+ {
+ *is_present = reader->isSecureElementPresent();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
READER_EXTERN_END;
- return service;
+ return result;
}
-EXTERN_API bool reader_is_secure_element_present(reader_h handle)
+EXTERN_API int reader_open_session_sync(reader_h handle, int *session_handle)
{
- bool result = false;
+ session_h session;
+ int result = SCARD_ERROR_OK;
READER_EXTERN_BEGIN;
- result = reader->isSecureElementPresent();
+
+ try
+ {
+ session = (session_h)reader->openSessionSync();
+ *session_handle = (int)session;
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *session_handle = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *session_handle = 0;
+ }
+
READER_EXTERN_END;
return result;
}
-EXTERN_API int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData)
+EXTERN_API int reader_close_sessions(reader_h handle)
{
- int result = -1;
+ int result = SCARD_ERROR_OK;
READER_EXTERN_BEGIN;
- result = reader->openSession((openSessionCallback)callback, userData);
+
+ try
+ {
+ reader->closeSessions();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
READER_EXTERN_END;
return result;
}
-EXTERN_API session_h reader_open_session_sync(reader_h handle)
+
+EXTERN_API se_service_h reader_get_se_service(reader_h handle)
{
- session_h result = NULL;
+ se_service_h service = NULL;
-#ifdef CLIENT_IPC_THREAD
READER_EXTERN_BEGIN;
- result = (session_h)reader->openSessionSync();
+ service = (se_service_h)reader->getSEService();
READER_EXTERN_END;
-#endif
- return result;
+ return service;
}
-EXTERN_API void reader_close_sessions(reader_h handle)
+EXTERN_API int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData)
{
+ int result = -1;
+
READER_EXTERN_BEGIN;
- reader->closeSessions();
+ result = reader->openSession((openSessionCallback)callback, userData);
READER_EXTERN_END;
+
+ return result;
}
EXTERN_API void reader_destroy_instance(reader_h handle)
#include <unistd.h>
#include <string.h>
#include <glib.h>
+#include <glib-object.h>
/* SLP library header */
/* local header */
#include "Debug.h"
-#include "ClientIPC.h"
-#include "ClientDispatcher.h"
#include "SEService.h"
+#include "ClientChannel.h"
#include "Reader.h"
-#include "Message.h"
+#include "ClientGDBus.h"
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
#endif
+#define SHUTDOWN_DELAY 500000 /* us */
+#define VERSION "3.0"
+
namespace smartcard_service_api
{
- SEService::SEService() :
- SEServiceHelper()
+ SEService::SEService() : SEServiceHelper(),
+ handle(-1), context(NULL), handler(NULL), listener(NULL),
+ version(VERSION)
{
- this->context = NULL;
- this->handler = NULL;
- this->listener = NULL;
- connected = false;
+ proxy = NULL;
}
SEService::SEService(void *user_data, serviceConnected handler)
throw(ErrorIO &, ErrorIllegalParameter &) :
- SEServiceHelper()
+ SEServiceHelper(), handle(-1),
+ listener(NULL), version(VERSION)
{
- this->listener = NULL;
- connected = false;
-
initialize(user_data, handler);
}
SEService::SEService(void *user_data, SEServiceListener *listener)
throw(ErrorIO &, ErrorIllegalParameter &) :
- SEServiceHelper()
+ SEServiceHelper(), handle(-1),
+ handler(NULL), version(VERSION)
{
- this->handler = NULL;
- connected = false;
-
initialize(user_data, listener);
}
- SEService::~SEService()
+ SEService::SEService(void *user_data)
+ throw(ErrorIO &, ErrorIllegalParameter &) :
+ SEServiceHelper(), handle(-1),
+ handler(NULL), version(VERSION)
{
- uint32_t i;
+ initializeSync(user_data);
+ }
+ SEService::~SEService()
+ {
try
{
+ size_t i;
+
shutdownSync();
+
+ for (i = 0; i < readers.size(); i++)
+ {
+ delete (Reader *)readers[i];
+ }
+
+ readers.clear();
}
- catch(ExceptionBase &e)
- {
- SCARD_DEBUG_ERR("EXCEPTION : %s", e.what());
- }
- catch(...)
+ catch (ExceptionBase &e)
{
- SCARD_DEBUG_ERR("EXCEPTION!!!");
+ _ERR("EXCEPTION : %s", e.what());
}
-
- for (i = 0; i < readers.size(); i++)
+ catch (...)
{
- delete (Reader *)readers[i];
+ _ERR("EXCEPTION!!!");
}
- readers.clear();
}
- SEService *SEService::createInstance(void *user_data, SEServiceListener *listener)
+ SEService *SEService::createInstance(void *user_data,
+ SEServiceListener *listener)
throw(ErrorIO &, ErrorIllegalParameter &)
{
return new SEService(user_data, listener);
}
- SEService *SEService::createInstance(void *user_data, serviceConnected handler)
+ SEService *SEService::createInstance(void *user_data,
+ serviceConnected handler)
throw(ErrorIO &, ErrorIllegalParameter &)
{
return new SEService(user_data, handler);
}
- void SEService::shutdown()
+ void SEService::reader_inserted(GObject *source_object,
+ guint reader_id, gchar *reader_name, gpointer user_data)
{
- if (connected == true)
+ Reader *reader = NULL;
+ SEService *service = (SEService *)user_data;
+
+ _INFO("[MSG_NOTIFY_SE_INSERTED]");
+
+ /* add readers */
+ reader = new Reader(service->context,
+ reader_name, GUINT_TO_POINTER(reader_id));
+ if (reader != NULL)
{
- uint32_t i;
+ service->readers.push_back(reader);
+ }
+ else
+ {
+ _ERR("alloc failed");
+ }
- for (i = 0; i < readers.size(); i++)
+ if (service->listener != NULL)
+ {
+ service->listener->eventHandler(service,
+ reader_name, 1, service->context);
+ }
+ else
+ {
+ _DBG("listener is null");
+ }
+ }
+
+ void SEService::reader_removed(GObject *source_object,
+ guint reader_id, gchar *reader_name, gpointer user_data)
+ {
+ SEService *service = (SEService *)user_data;
+ size_t i;
+
+ _INFO("[MSG_NOTIFY_SE_REMOVED]");
+
+ for (i = 0; i < service->readers.size(); i++)
+ {
+ if (((Reader *)service->readers[i])->handle ==
+ GUINT_TO_POINTER(reader_id))
{
- readers[i]->closeSessions();
+ ((Reader *)service->readers[i])->unavailable();
+ break;
}
+ }
- Message msg;
+ if (service->listener != NULL)
+ {
+ service->listener->eventHandler(service,
+ reader_name, 2, service->context);
+ }
+ else
+ {
+ _DBG("listener is null");
+ }
+ }
- msg.message = Message::MSG_REQUEST_SHUTDOWN;
- msg.error = (unsigned long)this; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)NULL;
+ void SEService::se_service_shutdown_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ SEService *service = (SEService *)user_data;
+ gint result;
+ GError *error = NULL;
+
+ if (smartcard_service_se_service_call_shutdown_finish(
+ SMARTCARD_SERVICE_SE_SERVICE(source_object),
+ &result, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ service->connected = false;
+ } else {
+ _ERR("smartcard_service_se_service_call_shutdown failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_se_service_call_shutdown failed, [%s]", error->message);
+ g_error_free(error);
+ }
+ }
- if (ClientIPC::getInstance().sendMessage(&msg) == false)
- {
- SCARD_DEBUG_ERR("time over");
+ void SEService::se_service_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ SEService *service = (SEService *)user_data;
+ gint result;
+ guint handle;
+ GVariant *readers = NULL;
+ GError *error = NULL;
+
+ if (service == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ if (smartcard_service_se_service_call_se_service_finish(
+ SMARTCARD_SERVICE_SE_SERVICE(source_object),
+ &result, &handle, &readers, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ service->connected = true;
+ service->handle = handle;
+ service->parseReaderInformation(readers);
+ }
+ } else {
+ _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (service->handler != NULL) {
+ service->handler(service, service->context);
+ } else if (service->listener != NULL) {
+ if (result == SCARD_ERROR_OK) {
+ service->listener->serviceConnected(service, service->context);
+ } else {
+ service->listener->errorHandler(service, result, service->context);
}
}
}
+ void SEService::shutdown()
+ {
+ shutdownSync();
+ }
+
void SEService::shutdownSync()
{
-#ifdef CLIENT_IPC_THREAD
if (connected == true)
{
uint32_t i;
readers[i]->closeSessions();
}
- /* send message to load se */
- Message msg;
+ gint result;
+ GError *error = NULL;
- msg.message = Message::MSG_REQUEST_SHUTDOWN;
- msg.error = (unsigned long)this; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+ if (smartcard_service_se_service_call_shutdown_sync(
+ (SmartcardServiceSeService *)proxy,
+ handle,
+ &result,
+ NULL,
+ &error) == false) {
+ _ERR("smartcard_service_se_service_call_shutdown_sync failed, [%s]", error->message);
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- int rv;
-
- rv = waitTimedCondition(0);
+ g_error_free(error);
+ }
- if (rv == 0)
- {
- ClientDispatcher::getInstance().removeSEService(context);
+ /* wait at least 500ms */
+ usleep(SHUTDOWN_DELAY);
- connected = false;
- }
- else
- {
- SCARD_DEBUG_ERR("time over");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- }
- syncUnlock();
+ connected = false;
}
-#endif
}
bool SEService::_initialize() throw(ErrorIO &)
{
bool result = false;
- ClientIPC *clientIPC;
- ClientDispatcher *clientDispatcher;
- SCARD_BEGIN();
+ _BEGIN();
+
+ /* init default context */
+ GError *error = NULL;
- /* initialize client */
- if (!g_thread_supported())
+ proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/SeService",
+ NULL, &error);
+ if (proxy == NULL)
{
- g_thread_init(NULL);
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return false;
}
- clientDispatcher = &ClientDispatcher::getInstance();
- clientIPC = &ClientIPC::getInstance();
+ g_signal_connect(proxy, "reader-inserted",
+ G_CALLBACK(&SEService::reader_inserted), this);
- clientIPC->setDispatcher(clientDispatcher);
+ g_signal_connect(proxy, "reader-removed",
+ G_CALLBACK(&SEService::reader_removed), this);
-#ifndef CLIENT_IPC_THREAD
- if (clientDispatcher->runDispatcherThread() == false)
- {
- SCARD_DEBUG_ERR("clientDispatcher->runDispatcherThread() failed");
+ /* request reader */
+ smartcard_service_se_service_call_se_service(
+ (SmartcardServiceSeService *)proxy,
+ NULL,
+ &SEService::se_service_cb,
+ this);
- return result;
- }
-#endif
+ _END();
- if (clientIPC->createConnectSocket() == false)
- {
- SCARD_DEBUG_ERR("clientIPC->createConnectSocket() failed");
+ return result;
+ }
- return result;
+ int SEService::_initialize_sync() throw(ErrorIO &)
+ {
+ gint result;
+ guint handle;
+ GError *error = NULL;
+ GVariant *readers = NULL;
+ SEService *service = (SEService *)this;
+
+ _BEGIN();
+
+ /* init default context */
+
+ proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/SeService",
+ NULL, &error);
+ if (proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return false;
}
- clientDispatcher->addSEService(context, this);
+ g_signal_connect(proxy, "reader-inserted",
+ G_CALLBACK(&SEService::reader_inserted), this);
- {
- /* send message to load se */
- Message msg;
+ g_signal_connect(proxy, "reader-removed",
+ G_CALLBACK(&SEService::reader_removed), this);
- msg.message = Message::MSG_REQUEST_READERS;
- msg.error = getpid(); /* using error to pid */
- msg.caller = (void *)this;
- msg.userParam = context;
+ /* request reader */
+ if(smartcard_service_se_service_call_se_service_sync(
+ (SmartcardServiceSeService *)proxy, &result, &handle, &readers, NULL, &error) == true)
+ {
+ if (result == SCARD_ERROR_OK)
+ {
+ service->connected = true;
+ service->handle = handle;
+ service->parseReaderInformation(readers);
+ }
+ }
+ else
+ {
+ _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
+ g_error_free(error);
- result = clientIPC->sendMessage(&msg);
+ result = SCARD_ERROR_IPC_FAILED;
}
- SCARD_END();
+ _END();
return result;
}
return _initialize();
}
- bool SEService::parseReaderInformation(unsigned int count, ByteArray data)
+ bool SEService::initializeSync(void *context)
+ throw(ErrorIO &, ErrorIllegalParameter &)
{
- size_t i;
- unsigned int offset = 0;
- unsigned int len = 0;
- void *handle = NULL;
- Reader *reader = NULL;
- char name[100];
+ this->context = context;
- for (i = 0; i < count && offset < data.getLength(); i++)
- {
- memset(name, 0, sizeof(name));
+ _initialize_sync();
+ return true;
+ }
- memcpy(&len, data.getBuffer(offset), sizeof(len));
- offset += sizeof(len);
+ bool SEService::parseReaderInformation(GVariant *variant)
+ {
+ Reader *reader = NULL;
- memcpy(name, data.getBuffer(offset), len);
- offset += len;
+ GVariantIter *iter;
+ guint handle;
+ gchar *name;
- memcpy(&handle, data.getBuffer(offset), sizeof(handle));
- offset += sizeof(handle);
+ g_variant_get(variant, "a(us)", &iter);
- SCARD_DEBUG("Reader [%d] : name [%s], handle [%p]", i, name, handle);
+ while (g_variant_iter_loop(iter, "(us)", &handle, &name) == true)
+ {
+ SECURE_LOGD("Reader : name [%s], handle [%08x]", name, handle);
/* add readers */
- reader = new Reader(context, name, handle);
+ reader = new Reader((void *)this->handle, name, GUINT_TO_POINTER(handle));
if (reader == NULL)
{
- SCARD_DEBUG_ERR("alloc failed");
+ _ERR("alloc failed");
continue;
}
readers.push_back(reader);
}
+ g_variant_iter_free(iter);
+
return true;
}
- bool SEService::dispatcherCallback(void *message)
+ bool SEService::parseReaderInformation(unsigned int count,
+ const ByteArray &data)
{
- 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;
+ size_t i;
+ unsigned int offset = 0;
+ unsigned int len = 0;
+ void *handle = NULL;
+ Reader *reader = NULL;
+ char name[100];
- switch (msg->message)
+ for (i = 0; i < count && offset < data.size(); i++)
{
- case Message::MSG_REQUEST_READERS :
- SCARD_DEBUG("[MSG_REQUEST_READERS]");
-
- service->connected = true;
-
- /* 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_REQUEST_SHUTDOWN :
- SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
-
- if (msg->isSynchronousCall() == true) /* synchronized call */
- {
- /* sync call */
- service->syncLock();
-
- /* copy result */
-// service->error = msg->error;
- service->signalCondition();
- service->syncUnlock();
- }
- else
- {
- /* Do nothing... */
- }
- break;
+ memset(name, 0, sizeof(name));
- case Message::MSG_NOTIFY_SE_INSERTED :
- {
- Reader *reader = NULL;
-
- SCARD_DEBUG("[MSG_NOTIFY_SE_INSERTED]");
-
- /* add readers */
- reader = new Reader(service->context,
- (char *)msg->data.getBuffer(), (void *)msg->param1);
- if (reader != NULL)
- {
- service->readers.push_back(reader);
- }
- else
- {
- SCARD_DEBUG_ERR("alloc failed");
- }
-
- if (service->listener != NULL)
- {
- service->listener->eventHandler(service,
- (char *)msg->data.getBuffer(), 1, service->context);
- }
- else
- {
- SCARD_DEBUG("listener is null");
- }
- }
- break;
+ memcpy(&len, data.getBuffer(offset), sizeof(len));
+ offset += sizeof(len);
- case Message::MSG_NOTIFY_SE_REMOVED :
- {
- size_t i;
-
- SCARD_DEBUG("[MSG_NOTIFY_SE_REMOVED]");
-
- for (i = 0; i < service->readers.size(); i++)
- {
- if (((Reader *)service->readers[i])->handle == (void *)msg->param1)
- {
- ((Reader *)service->readers[i])->present = false;
- break;
- }
- }
-
- if (service->listener != NULL)
- {
- service->listener->eventHandler(service,
- (char *)msg->data.getBuffer(), 2, service->context);
- }
- else
- {
- SCARD_DEBUG("listener is null");
- }
- }
- break;
+ memcpy(name, data.getBuffer(offset), len);
+ offset += len;
- case Message::MSG_OPERATION_RELEASE_CLIENT :
- SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
+ memcpy(&handle, data.getBuffer(offset), sizeof(handle));
+ offset += sizeof(handle);
- if (service->listener != NULL)
- {
- service->listener->errorHandler(service, msg->error, service->context);
+ SECURE_LOGD("Reader [%d] : name [%s], handle [%p]", i, name, handle);
- ClientDispatcher::getInstance().removeSEService(service->context);
- service->connected = false;
- }
- else
+ /* add readers */
+ reader = new Reader(context, name, handle);
+ if (reader == NULL)
{
- SCARD_DEBUG_ERR("service->listener is null");
+ _ERR("alloc failed");
+ continue;
}
- break;
- default :
- SCARD_DEBUG("unknown message [%s]", msg->toString());
- break;
+ readers.push_back(reader);
}
- SCARD_END();
-
- return result;
+ return true;
}
-
} /* namespace smartcard_service_api */
/* export C API */
} \
else \
{ \
- SCARD_DEBUG_ERR("Invalid param"); \
+ _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)
+EXTERN_API se_service_h se_service_create_instance(void *user_data,
+ se_service_connected_cb callback)
{
SEService *service;
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)
+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;
return (se_service_h)service;
}
+EXTERN_API se_service_h se_service_create_instance_sync(void *user_data,
+ int *result)
+{
+ SEService *service;
+
+ try
+ {
+ service = new SEService(user_data);
+ }
+ catch (ExceptionBase &e)
+ {
+ *result = e.getErrorCode();
+ service = NULL;
+ }
+ catch (...)
+ {
+ *result = SCARD_ERROR_UNKNOWN;
+ service = NULL;
+ }
+
+ return (se_service_h)service;
+}
+
+EXTERN_API int se_service_get_version(se_service_h handle, char **version_str)
+{
+ int ret = 0;
+
+ if (version_str == NULL) {
+ return SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ SE_SERVICE_EXTERN_BEGIN;
+
+ *version_str = g_strdup(service->getVersion());
+
+ SE_SERVICE_EXTERN_END;
+
+ return ret;
+}
+
EXTERN_API int se_service_get_readers_count(se_service_h handle)
{
int count = 0;
return count;
}
-EXTERN_API bool se_service_get_readers(se_service_h handle, reader_h *readers, int *count)
+EXTERN_API int se_service_get_readers(se_service_h handle, int *readers, int *count)
{
- bool result = false;
+ int result = 0;
SE_SERVICE_EXTERN_BEGIN;
{
if (temp_readers[i]->isSecureElementPresent())
{
- readers[i] = (reader_h)temp_readers[i];
+ readers[i] = (int)temp_readers[i];
temp++;
}
}
{
SE_SERVICE_EXTERN_BEGIN;
- service->shutdown();
+ service->shutdownSync();
SE_SERVICE_EXTERN_END;
}
-EXTERN_API void se_service_destroy_instance(se_service_h handle)
+EXTERN_API int se_service_destroy_instance(se_service_h handle)
{
+ int result = 0;
+
SE_SERVICE_EXTERN_BEGIN;
delete service;
SE_SERVICE_EXTERN_END;
+
+ return result;
}
#include "Session.h"
#include "Reader.h"
#include "ClientChannel.h"
-#include "ClientIPC.h"
+#include "ClientGDBus.h"
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
if (context == NULL || handle == NULL)
{
- SCARD_DEBUG_ERR("handle is null");
+ _ERR("handle is null");
return;
}
this->context = context;
this->handle = handle;
+
+ /* init default context */
+ GError *error = NULL;
+
+ proxy = smartcard_service_session_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/Session",
+ NULL, &error);
+ if (proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
closed = false;
}
}
}
- ByteArray Session::getATRSync()
+ void Session::session_get_atr_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ Session *session;
+ getATRCallback callback;
+ gint result;
+ GVariant *var_atr;
+ GError *error = NULL;
+ ByteArray atr;
+
+ _INFO("MSG_REQUEST_GET_ATR");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ session = (Session *)param->instance;
+ callback = (getATRCallback)param->callback;
+
+ if (smartcard_service_session_call_get_atr_finish(
+ SMARTCARD_SERVICE_SESSION(source_object),
+ &result, &var_atr, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ GDBusHelper::convertVariantToByteArray(var_atr, atr);
+
+ session->atr = atr;
+ } else {
+ _ERR("smartcard_service_session_call_get_atr failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_get_atr failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(atr.getBuffer(),
+ atr.size(), result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ void Session::session_open_channel_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ Session *session;
+ openChannelCallback callback;
+ gint result = SCARD_ERROR_UNKNOWN;
+ gint channel_number;
+ guint channel_id;
+ GVariant *var_response;
+ GError *error = NULL;
+ Channel *channel = NULL;
+
+ _INFO("MSG_REQUEST_OPEN_CHANNEL");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ session = (Session *)param->instance;
+ callback = (openChannelCallback)param->callback;
+
+ if (smartcard_service_session_call_open_channel_finish(
+ SMARTCARD_SERVICE_SESSION(source_object),
+ &result, &channel_id, &channel_number, &var_response,
+ res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ ByteArray response;
+
+ GDBusHelper::convertVariantToByteArray(
+ var_response, response);
+
+ /* create new instance of channel */
+ channel = new ClientChannel(session->context,
+ session, channel_id,
+ response, (void *)channel_id);
+ if (channel != NULL) {
+ session->channels.push_back(channel);
+ } else {
+ _ERR("alloc failed");
+
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ _ERR("smartcard_service_session_call_open_channel failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_open_channel failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(channel, result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ void Session::session_close_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ Session *session;
+ closeSessionCallback callback;
+ gint result;
+ GError *error = NULL;
+
+ _INFO("MSG_REQUEST_CLOSE_SESSION");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ session = (Session *)param->instance;
+ callback = (closeSessionCallback)param->callback;
+
+ if (smartcard_service_session_call_close_session_finish(
+ SMARTCARD_SERVICE_SESSION(source_object),
+ &result, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ session->closed = true;
+ } else {
+ _ERR("smartcard_service_session_call_close_session failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_close_session failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ const ByteArray Session::getATRSync()
throw (ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &)
{
ByteArray result;
+
if (getReader()->isSecureElementPresent() == true)
{
if (atr.isEmpty() == true)
{
- Message msg;
- int rv;
-
-#ifdef CLIENT_IPC_THREAD
- /* request channel handle from server */
- msg.message = Message::MSG_REQUEST_GET_ATR;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
-
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- rv = waitTimedCondition(0);
- if (rv != 0)
- {
- SCARD_DEBUG_ERR("time over");
- this->error = SCARD_ERROR_OPERATION_TIMEOUT;
+ gint ret;
+ GVariant *var_atr = NULL;
+ GError *error = NULL;
+
+ if (smartcard_service_session_call_get_atr_sync(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ &ret, &var_atr, NULL, &error) == true) {
+ if (ret == SCARD_ERROR_OK) {
+ GDBusHelper::convertVariantToByteArray(var_atr, result);
+
+ atr = result;
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", ret);
+
+ THROW_ERROR(ret);
}
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- this->error = SCARD_ERROR_IPC_FAILED;
- }
- syncUnlock();
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
+ g_error_free(error);
- if (this->error != SCARD_ERROR_OK)
- {
- ThrowError::throwError(this->error);
+ THROW_ERROR(SCARD_ERROR_IPC_FAILED);
}
-#endif
}
result = atr;
}
else
{
- SCARD_DEBUG_ERR("unavailable session");
+ _ERR("unavailable session");
throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
}
{
if (atr.isEmpty() == true)
{
- Message msg;
+ CallbackParam *param = new CallbackParam();
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userData;
- /* request channel handle from server */
- msg.message = Message::MSG_REQUEST_GET_ATR;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)callback;
- msg.userParam = userData;
+ smartcard_service_session_call_get_atr(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle), NULL,
+ &Session::session_get_atr_cb, param);
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- result = SCARD_ERROR_OK;
- }
- else
- {
- result = SCARD_ERROR_IPC_FAILED;
- }
+ result = SCARD_ERROR_OK;
}
else
{
result = SCARD_ERROR_OK;
/* TODO : invoke callback directly */
- callback(atr.getBuffer(), atr.getLength(), 0, userData);
+ callback(atr.getBuffer(),
+ atr.size(), 0, userData);
}
}
else
{
- SCARD_DEBUG_ERR("unavailable session");
+ _ERR("unavailable session");
result = SCARD_ERROR_ILLEGAL_STATE;
}
throw (ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &)
{
- Message msg;
- int rv;
-
-#ifdef CLIENT_IPC_THREAD
if (isClosed() == false)
{
closed = true;
closeChannels();
- /* request channel handle from server */
- msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+ gint ret;
+ GError *error = NULL;
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- rv = waitTimedCondition(0);
+ if (smartcard_service_session_call_close_session_sync(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ &ret, NULL, &error) == true) {
+ if (ret == SCARD_ERROR_OK) {
+ closed = true;
+ } else {
+ _ERR("smartcard_service_session_call_close_session_sync failed, [%d]", ret);
- if (rv != 0)
- {
- SCARD_DEBUG_ERR("time over");
- this->error = SCARD_ERROR_OPERATION_TIMEOUT;
+ THROW_ERROR(ret);
}
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- this->error = SCARD_ERROR_IPC_FAILED;
- }
- syncUnlock();
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
+ g_error_free(error);
- if (this->error != SCARD_ERROR_OK)
- {
- ThrowError::throwError(this->error);
+ THROW_ERROR(SCARD_ERROR_IPC_FAILED);
}
}
-#endif
}
int Session::close(closeSessionCallback callback, void *userData)
{
int result = SCARD_ERROR_OK;
- Message msg;
if (isClosed() == false)
{
closed = true;
closeChannels();
- /* request channel handle from server */
- msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)callback;
- msg.userParam = userData;
+ CallbackParam *param = new CallbackParam();
- if (ClientIPC::getInstance().sendMessage(&msg) == false)
- {
- result = SCARD_ERROR_IPC_FAILED;
- }
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userData;
+
+ smartcard_service_session_call_close_session(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle), NULL,
+ &Session::session_close_cb, param);
}
return result;
}
- unsigned int Session::getChannelCountSync()
+ size_t Session::getChannelCount() const
{
- channelCount = -1;
+ size_t count = 0;
if (getReader()->isSecureElementPresent() == true)
{
- Message msg;
- int rv;
-
-
-#ifdef CLIENT_IPC_THREAD
- /* request channel handle from server */
- msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
-
- channelCount = -1;
-
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- rv = waitTimedCondition(0);
- if (rv != 0)
- {
- SCARD_DEBUG_ERR("time over");
- this->error = SCARD_ERROR_OPERATION_TIMEOUT;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- this->error = SCARD_ERROR_IPC_FAILED;
- }
- syncUnlock();
-
- if (this->error != SCARD_ERROR_OK)
- {
- ThrowError::throwError(this->error);
- }
-#endif
+ count = channels.size();
}
else
{
- SCARD_DEBUG_ERR("unavailable session");
+ _ERR("unavailable session");
throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
}
- return channelCount;
+ return count;
}
-
- int Session::getChannelCount(getChannelCountCallback callback, void *userData)
+ Channel *Session::openChannelSync(int id, const ByteArray &aid)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
{
- int result;
-
- if (getReader()->isSecureElementPresent() == true)
- {
- Message msg;
-
-
- msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)callback;
- msg.userParam = userData;
-
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- result = SCARD_ERROR_OK;
- }
- else
- {
- result = SCARD_ERROR_IPC_FAILED;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("unavailable session");
- result = SCARD_ERROR_ILLEGAL_STATE;
- }
-
- return result;
+ return openChannelSync(id, aid, 0x00);
}
- Channel *Session::openChannelSync(int id, ByteArray aid)
+ Channel *Session::openChannelSync(int id, const ByteArray &aid, unsigned char P2)
throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &)
{
- openedChannel = NULL;
+ Channel *channel = NULL;
if (getReader()->isSecureElementPresent() == true)
{
- Message msg;
- int rv;
-
-#ifdef CLIENT_IPC_THREAD
- /* request channel handle from server */
- msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
- msg.param1 = id;
- msg.param2 = (unsigned long)handle;
- msg.data = aid;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
-
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- rv = waitTimedCondition(0);
- if (rv != 0)
- {
- SCARD_DEBUG_ERR("time over");
- this->error = SCARD_ERROR_OPERATION_TIMEOUT;
+ gint ret;
+ GVariant *var_aid = NULL, *var_response = NULL;
+ guint channel_id;
+ gint channel_number;
+ GError *error = NULL;
+
+ var_aid = GDBusHelper::convertByteArrayToVariant(aid);
+
+ if (smartcard_service_session_call_open_channel_sync(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ (guint)id, var_aid, (guint8)P2, &ret, &channel_id, &channel_number,
+ &var_response, NULL, &error) == true) {
+ if (ret == SCARD_ERROR_OK && channel_id != 0) {
+ ByteArray response;
+
+ GDBusHelper::convertVariantToByteArray(
+ var_response, response);
+
+ /* create new instance of channel */
+ channel = new ClientChannel(context,
+ this, channel_number,
+ response, (void *)channel_id);
+ if (channel != NULL)
+ {
+ channels.push_back(channel);
+ }
+ else
+ {
+ _ERR("alloc failed");
+
+ THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_open_channel_sync failed, [%d]", ret);
+
+ THROW_ERROR(ret);
}
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- this->error = SCARD_ERROR_IPC_FAILED;
- }
- syncUnlock();
-#endif
- if (this->error != SCARD_ERROR_OK)
- {
- ThrowError::throwError(this->error);
+ } else {
+ _ERR("smartcard_service_session_call_open_channel_sync failed, [%s]", error->message);
+ g_error_free(error);
+
+ THROW_ERROR(SCARD_ERROR_IPC_FAILED);
}
}
else
{
- SCARD_DEBUG_ERR("unavailable session");
+ _ERR("unavailable session");
+
throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
}
- return (Channel *)openedChannel;
+ return (Channel *)channel;
}
- int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
+ int Session::openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData)
{
int result;
if (getReader()->isSecureElementPresent() == true)
{
- Message msg;
-
- /* request channel handle from server */
- msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
- msg.param1 = id;
- msg.param2 = (unsigned long)handle;
- msg.data = aid;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)callback;
- msg.userParam = userData;
-
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- result = SCARD_ERROR_OK;
- }
- else
- {
- result = SCARD_ERROR_IPC_FAILED;
- }
+ GVariant *var_aid;
+
+ CallbackParam *param = new CallbackParam();
+
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userData;
+
+ var_aid = GDBusHelper::convertByteArrayToVariant(aid);
+
+ smartcard_service_session_call_open_channel(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ (guint)id, var_aid, 0, NULL,
+ &Session::session_open_channel_cb, param);
+
+ result = SCARD_ERROR_OK;
}
else
{
- SCARD_DEBUG_ERR("unavailable session");
+ _ERR("unavailable session");
result = SCARD_ERROR_ILLEGAL_STATE;
}
return result;
}
- Channel *Session::openBasicChannelSync(ByteArray aid)
- throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
+ Channel *Session::openBasicChannelSync(const ByteArray &aid)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
{
- return openChannelSync(0, aid);
+ return openChannelSync(0, aid, 0x00);
}
- Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
- throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
+ Channel *Session::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
{
- return openBasicChannelSync(ByteArray(aid, length));
+ return openChannelSync(0, aid, P2);
}
- int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
+ Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
{
- return openChannel(0, aid, callback, userData);
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp, 0x00);
}
- int Session::openBasicChannel(unsigned char *aid, unsigned int length,
- openChannelCallback callback, void *userData)
+ Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
{
- return openBasicChannel(ByteArray(aid, length), callback, userData);
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp, P2);
}
- Channel *Session::openLogicalChannelSync(ByteArray aid)
- throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
+ int Session::openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
{
- return openChannelSync(1, aid);
+ return openChannel(0, aid, callback, userData);
}
- Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
- throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
+ int Session::openBasicChannel(const unsigned char *aid, unsigned int length,
+ openChannelCallback callback, void *userData)
{
- return openLogicalChannelSync(ByteArray(aid, length));
+ ByteArray temp(aid, length);
+
+ return openBasicChannel(temp, callback, userData);
}
- int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
+ Channel *Session::openLogicalChannelSync(const ByteArray &aid)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
{
- return openChannel(1, aid, callback, userData);
+ return openChannelSync(1, aid, 0x00);
}
- int Session::openLogicalChannel(unsigned char *aid, unsigned int length,
- openChannelCallback callback, void *userData)
+ Channel *Session::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
{
- return openLogicalChannel(ByteArray(aid, length), callback, userData);
+ return openChannelSync(1, aid, P2);
}
- bool Session::dispatcherCallback(void *message)
+ Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
{
- 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 = SCARD_ERROR_OUT_OF_MEMORY;
- }
- }
+ ByteArray temp(aid, length);
- if (msg->isSynchronousCall() == true) /* 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->isSynchronousCall() == true) /* 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->isSynchronousCall() == true) /* 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->isSynchronousCall() == true) /* synchronized call */
- {
- /* sync call */
- session->syncLock();
+ return openLogicalChannelSync(temp, 0x00);
+ }
- session->error = msg->error;
- session->channelCount = msg->param1;
+ Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ ByteArray temp(aid, length);
- session->signalCondition();
- session->syncUnlock();
- }
- else if (msg->callback != NULL)
- {
- getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
+ return openLogicalChannelSync(temp, P2);
+ }
- /* async call */
- cb(msg->param1, msg->error, msg->userParam);
- }
- }
- break;
+ int Session::openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
+ {
+ return openChannel(1, aid, callback, userData);
+ }
- default :
- SCARD_DEBUG("unknown message : %s", msg->toString());
- break;
- }
+ int Session::openLogicalChannel(const unsigned char *aid, unsigned int length,
+ openChannelCallback callback, void *userData)
+ {
+ ByteArray temp(aid, length);
- return result;
+ return openLogicalChannel(temp, callback, userData);
}
} /* namespace smartcard_service_api */
} \
else \
{ \
- SCARD_DEBUG_ERR("Invalid param"); \
+ _ERR("Invalid param"); \
}
using namespace smartcard_service_api;
-EXTERN_API reader_h session_get_reader(session_h handle)
+EXTERN_API int session_get_reader(session_h handle, int* reader_handle)
{
+ int result = SCARD_ERROR_OK;
reader_h reader = NULL;
SESSION_EXTERN_BEGIN;
+
+ try
+ {
reader = session->getReader();
+ *reader_handle = (int)reader;
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *reader_handle = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *reader_handle = 0;
+ }
+
SESSION_EXTERN_END;
- return reader;
+ return result;
}
-EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
+EXTERN_API int session_is_closed(session_h handle, bool* is_closed)
{
- int result = -1;
+ int result = SCARD_ERROR_OK;
SESSION_EXTERN_BEGIN;
- result = session->getATR((getATRCallback)callback, userData);
+
+ try
+ {
+ *is_closed = session->isClosed();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
SESSION_EXTERN_END;
return result;
}
-EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
+EXTERN_API int session_close_channels(session_h handle)
{
- int result = -1;
+ int result = SCARD_ERROR_OK;
SESSION_EXTERN_BEGIN;
- result = session->close((closeSessionCallback)callback, userData);
+
+ try
+ {
+ session->closeChannels();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
SESSION_EXTERN_END;
return result;
}
-EXTERN_API bool session_is_closed(session_h handle)
+EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
{
- bool result = false;
+ ByteArray temp;
+ int result = SCARD_ERROR_OK;
SESSION_EXTERN_BEGIN;
- result = session->isClosed();
+
+ try
+ {
+ temp = session->getATRSync();
+
+ if (temp.size() > 0)
+ {
+ *buffer = (unsigned char *)calloc(temp.size(), sizeof(char));
+ *length = temp.size();
+
+ memcpy(*buffer, temp.getBuffer(), *length);
+ }
+ }
+ catch (ErrorIllegalState &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+
+ if(result == SCARD_ERROR_OPERATION_NOT_SUPPORTED)
+ {
+ *length = 0;
+ result = SCARD_ERROR_OK;
+ }
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *length = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *length = 0;
+ }
+
SESSION_EXTERN_END;
return result;
}
-EXTERN_API void session_close_channels(session_h handle)
+EXTERN_API int session_close_sync(session_h handle)
{
+ int result = SCARD_ERROR_OK;
+
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;
+ try
+ {
+ session->closeSync();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
- 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)
+EXTERN_API int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
+ unsigned int length, unsigned char P2, int* channel_handle)
{
- int result = -1;
+ int result = SCARD_ERROR_OK;
SESSION_EXTERN_BEGIN;
- result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
+
+ try
+ {
+ *channel_handle = (int)session->openBasicChannelSync(aid, length, P2);
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *channel_handle = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *channel_handle = 0;
+ }
+
SESSION_EXTERN_END;
return result;
}
-EXTERN_API int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
+EXTERN_API int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
+ unsigned int length, unsigned char P2, int* channel_handle)
{
- int result = -1;
+ int result = SCARD_ERROR_OK;
SESSION_EXTERN_BEGIN;
- result = session->getChannelCount((getChannelCountCallback)callback, userData);
+
+ try
+ {
+ *channel_handle = (int)session->openLogicalChannelSync(aid, length, P2);
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *channel_handle = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *channel_handle = 0;
+ }
+
SESSION_EXTERN_END;
return result;
}
-EXTERN_API void session_destroy_instance(session_h handle)
-{
-}
-
-EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
+EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
{
- ByteArray temp;
int result = -1;
-#ifdef CLIENT_IPC_THREAD
- if (buffer == NULL || length == NULL)
- return result;
-
SESSION_EXTERN_BEGIN;
- temp = session->getATRSync();
- if (temp.getLength() > 0)
- {
- *length = temp.getLength();
- *buffer = (unsigned char *)calloc(1, *length);
- memcpy(*buffer, temp.getBuffer(), *length);
-
- result = 0;
- }
- SESSION_EXTERN_END;
-#endif
+ result = session->getATR((getATRCallback)callback, userData);
+ SESSION_EXTERN_END;
return result;
}
-EXTERN_API void session_close_sync(session_h handle)
+EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
{
-#ifdef CLIENT_IPC_THREAD
+ int result = -1;
+
SESSION_EXTERN_BEGIN;
- session->closeSync();
+ result = session->close((closeSessionCallback)callback, userData);
SESSION_EXTERN_END;
-#endif
+
+ return result;
}
-EXTERN_API channel_h session_open_basic_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
+EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
+ unsigned int length, session_open_channel_cb callback, void *userData)
{
- channel_h result = NULL;
+ int result = -1;
-#ifdef CLIENT_IPC_THREAD
SESSION_EXTERN_BEGIN;
- result = session->openBasicChannelSync(aid, length);
+ result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
SESSION_EXTERN_END;
-#endif
return result;
}
-EXTERN_API channel_h session_open_logical_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
+EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
+ unsigned int length, session_open_channel_cb callback, void *userData)
{
- channel_h result = NULL;
+ int result = -1;
-#ifdef CLIENT_IPC_THREAD
SESSION_EXTERN_BEGIN;
- result = session->openLogicalChannelSync(aid, length);
+ result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
SESSION_EXTERN_END;
-#endif
return result;
}
-EXTERN_API unsigned int session_get_channel_count_sync(session_h handle)
+EXTERN_API size_t session_get_channel_count(session_h handle)
{
- unsigned int result = 0;
+ size_t result = 0;
-#ifdef CLIENT_IPC_THREAD
SESSION_EXTERN_BEGIN;
- result = session->getChannelCountSync();
+ result = session->getChannelCount();
SESSION_EXTERN_END;
-#endif
return result;
}
+
+EXTERN_API void session_destroy_instance(session_h handle)
+{
+}
+
#define CLIENTCHANNEL_H_
/* standard library header */
+#include <gio/gio.h>
/* SLP library header */
private:
void *context;
void *handle;
- /* temporary data for sync function */
- int error;
- ByteArray response;
+ void *proxy;
ClientChannel(void *context, Session *session, int channelNum,
- ByteArray selectResponse, void *handle);
+ const ByteArray &selectResponse, void *handle);
~ClientChannel();
- static bool dispatcherCallback(void *message);
+ static void channel_transmit_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+ static void channel_close_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
public:
- int close(closeCallback callback, void *userParam);
- int transmit(ByteArray command, transmitCallback callback,
- void *userParam);
+ int close(closeChannelCallback callback, void *userParam);
+ int transmit(const ByteArray &command,
+ transmitCallback callback, void *userParam);
+ bool selectNext(){ return false; }
void closeSync()
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorSecurity &, ErrorIllegalParameter &);
- int transmitSync(ByteArray command, ByteArray &result)
+ int transmitSync(const ByteArray &command, ByteArray &result)
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
- friend class ClientDispatcher;
+ void *getHandle(){ return handle; }
+
friend class Session;
};
-
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
{
#endif /* __cplusplus */
-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) __attribute__((deprecated)) ;
+int channel_is_basic_channel(channel_h handle, bool* is_basic_channel);
+int channel_is_closed(channel_h handle, bool* is_closed );
+int channel_get_session(channel_h handle, int *session_handle);
+int channel_close_sync(channel_h handle);
+int channel_transmit_sync(channel_h handle, unsigned char *command,
+ unsigned int cmd_len, unsigned char **response, unsigned int *resp_len);
+int channel_get_select_response(channel_h handle,
+ unsigned char *buffer, size_t* length);
+int channel_get_transmit_response(channel_h handle,
+ unsigned char *buffer, size_t* length);
+int channel_select_next(channel_h hChannel, bool *pSuccess);
+////
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);
-void channel_close_sync(channel_h handle);
-int channel_transmit_sync(channel_h handle, unsigned char *command,
- unsigned int cmd_len, unsigned char **response, unsigned int *resp_len);
+unsigned int channel_get_select_response_length(channel_h handle);
+void channel_destroy_instance(channel_h handle) __attribute__((deprecated));
+
#ifdef __cplusplus
}
* limitations under the License.
*/
+#ifndef CLIENTGDBUS_H_
+#define CLIENTGDBUS_H_
+
/* standard library header */
-#include <stdio.h>
+#include <glib.h>
/* SLP library header */
/* local header */
-#include "Debug.h"
-#include "SEServiceHelper.h"
+#include "GDBusHelper.h"
+#include "smartcard-service-gdbus.h"
namespace smartcard_service_api
{
- SEServiceHelper::~SEServiceHelper()
+ class ClientGDBus
{
- SCARD_BEGIN();
- SCARD_END();
- }
-
+ };
} /* namespace smartcard_service_api */
+
+#endif /* CLIENTGDBUS_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CLIENTIPC_H_
-#define CLIENTIPC_H_
-
-/* standard library header */
-#ifdef USE_AUTOSTART
-#include <dbus/dbus-glib.h>
-#endif
-
-/* SLP library header */
-
-/* local header */
-#include "IPCHelper.h"
-#include "SEServiceListener.h"
-#ifdef USE_AUTOSTART
-#include "smartcard-service-glue.h"
-#endif
-
-namespace smartcard_service_api
-{
- class ClientIPC: public IPCHelper
- {
- private:
-#ifdef SECURITY_SERVER
- ByteArray cookie;
-#endif
- ClientIPC();
- ~ClientIPC();
-
-#ifdef USE_AUTOSTART
- void _launch_daemon();
-#endif
- int handleIOErrorCondition(void *channel, GIOCondition condition);
- int handleInvalidSocketCondition(void *channel, GIOCondition condition);
- int handleIncomingCondition(void *channel, GIOCondition condition);
-
- public:
- static ClientIPC &getInstance();
- bool sendMessage(Message *msg);
- };
-
-} /* namespace open_mobile_api */
-#endif /* CLIENTIPC_H_ */
#define READER_H_
/* standard library header */
+#include <glib.h>
+#include <gio/gio.h>
/* SLP library header */
private:
void *context;
void *handle;
- /* temporary data for sync function */
- int error;
- Session *openedSession;
+ void *proxy;
Reader(void *context, const char *name, void *handle);
~Reader();
- void unavailable();
-
- static bool dispatcherCallback(void *message);
+ inline void unavailable() { present = false; }
+ static void reader_open_session_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
public:
void closeSessions()
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
+ void *getHandle(){ return handle; }
+
friend class SEService;
- friend class ClientDispatcher;
};
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
{
#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_get_name(reader_h handle, char** reader_name);
+int reader_is_secure_element_present(reader_h handle, bool* is_present);
+int reader_open_session_sync(reader_h handle, int *session_handle);
+int reader_close_sessions(reader_h handle);
+///
+
int reader_open_session(reader_h handle, reader_open_session_cb callback,
void *userData);
-session_h reader_open_session_sync(reader_h handle);
-void reader_close_sessions(reader_h handle);
+se_service_h reader_get_se_service(reader_h handle);
__attribute__((deprecated)) void reader_destroy_instance(reader_h handle);
#ifdef __cplusplus
#define SESERVICE_H_
/* standard library header */
+#include <glib.h>
+#include <gio/gio.h>
/* SLP library header */
{
typedef void (*serviceConnected)(SEServiceHelper *service, void *context);
- class SEService: public SEServiceHelper
+ class SEService : public SEServiceHelper
{
private:
- int pid;
+ unsigned int handle;
void *context;
serviceConnected handler;
SEServiceListener *listener;
+ void *proxy;
+ const char *version;
SEService();
- static bool dispatcherCallback(void *message);
- bool parseReaderInformation(unsigned int count, ByteArray data);
+ void addReader(unsigned int handle, const char *name);
+ bool parseReaderInformation(unsigned int count, const ByteArray &data);
+ bool parseReaderInformation(GVariant *variant);
bool _initialize()
throw(ErrorIO &);
throw(ErrorIO &, ErrorIllegalParameter &);
bool initialize(void *context, SEServiceListener *listener)
throw(ErrorIO &, ErrorIllegalParameter &);
- SEService *initializeSync(void *context, serviceConnected handler)
+ int _initialize_sync()
+ throw(ErrorIO &);
+ bool initializeSync(void *context)
throw(ErrorIO &, ErrorIllegalParameter &);
+ static void reader_inserted(GObject *source_object,
+ guint reader_id, gchar *reader_name,
+ gpointer user_data);
+ static void reader_removed(GObject *source_object,
+ guint reader_id, gchar *reader_name,
+ gpointer user_data);
+ static void se_service_shutdown_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+ static void se_service_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+
public:
SEService(void *user_data, serviceConnected handler)
throw(ErrorIO &, ErrorIllegalParameter &);
SEService(void *user_data, SEServiceListener *listener)
throw(ErrorIO &, ErrorIllegalParameter &);
+ SEService(void *user_data)
+ throw(ErrorIO &, ErrorIllegalParameter &);
~SEService();
static SEService *createInstance(void *user_data, SEServiceListener *listener)
void shutdown();
void shutdownSync();
-
- friend class ClientDispatcher;
+ const char *getVersion() const { return version; }
};
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
{
#endif /* __cplusplus */
-se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback);
+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);
+ se_service_connected_cb connected, se_service_event_cb event,
+ se_sesrvice_error_cb error);
+
+se_service_h se_service_create_instance_sync(void *user_data, int* result);
+int se_service_get_version(se_service_h handle, char **version_str);
int se_service_get_readers_count(se_service_h handle);
-bool se_service_get_readers(se_service_h handle, reader_h *readers, int *count);
+int se_service_get_readers(se_service_h handle, int *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);
+int se_service_destroy_instance(se_service_h handle);
+
#ifdef __cplusplus
}
#define SESSION_H_
/* standard library header */
+#include <gio/gio.h>
/* SLP library header */
{
class Reader;
- class Session: public SessionHelper
+ class Session : public SessionHelper
{
private:
void *context;
void *handle;
- /* temporary data for sync function */
- int error;
- Channel *openedChannel;
- unsigned int channelCount;
+ void *proxy;
Session(void *context, Reader *reader, void *handle);
~Session();
- int openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData);
- static bool dispatcherCallback(void *message);
+ int openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData);
+
+ Channel *openChannelSync(int id, const ByteArray &aid)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openChannelSync(int id, ByteArray aid)
+ Channel *openChannelSync(int id, const ByteArray &aid, unsigned char P2)
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
+ static void session_get_atr_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+ static void session_open_channel_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+ static void session_close_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+
public:
void closeChannels()
throw(ErrorIO &, ErrorIllegalState &);
int getATR(getATRCallback callback, void *userData);
int close(closeSessionCallback callback, void *userData);
- 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);
- int getChannelCount(getChannelCountCallback callback, void * userData);
+ int openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData);
+ int openBasicChannel(const unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
+ int openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData);
+ int openLogicalChannel(const unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
- ByteArray getATRSync()
+ const ByteArray getATRSync()
throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &);
throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &);
- Channel *openBasicChannelSync(ByteArray aid)
- throw(ErrorIO &, ErrorIllegalState &,
+ Channel *openBasicChannelSync(const ByteArray &aid)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openBasicChannelSync(unsigned char *aid, unsigned int length)
- throw(ErrorIO &, ErrorIllegalState &,
+ Channel *openBasicChannelSync(const unsigned char *aid, unsigned int length)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openLogicalChannelSync(ByteArray aid)
- throw(ErrorIO &, ErrorIllegalState &,
+ Channel *openLogicalChannelSync(const ByteArray &aid)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length)
- throw(ErrorIO &, ErrorIllegalState &,
+ Channel *openLogicalChannelSync(const unsigned char *aid, unsigned int length)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openBasicChannelSync(const ByteArray &aid, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
- unsigned int getChannelCountSync();
+ Channel *openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ size_t getChannelCount() const;
+ void *getHandle(){ return handle; }
- friend class ClientDispatcher;
friend class Reader;
};
-
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
{
#endif /* __cplusplus */
-reader_h session_get_reader(session_h handle);
-bool session_is_closed(session_h handle);
-__attribute__((deprecated)) void session_destroy_instance(session_h handle);
-void session_close_channels(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);
-
+int session_get_reader(session_h handle, int* reader_handle);
+int session_is_closed(session_h handle, bool* is_closed);
+int session_close_channels(session_h handle);
+int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length);
+int session_close_sync(session_h handle);
+int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
+ unsigned int length, unsigned char P2, int* channel_handle);
+int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
+ unsigned int length, unsigned char P2, int* channel_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);
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);
-int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData);
+size_t session_get_channel_count(session_h handle);
+__attribute__((deprecated)) void session_destroy_instance(session_h handle);
-int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length);
-void session_close_sync(session_h handle);
-channel_h session_open_basic_channel_sync(session_h handle, unsigned char *aid, unsigned int length);
-channel_h session_open_logical_channel_sync(session_h handle, unsigned char *aid, unsigned int length);
-unsigned int session_get_channel_count_sync(session_h handle);
#ifdef __cplusplus
}
#define SMARTCARD_SERVICE_H_
#include "smartcard-types.h"
+#ifdef __cplusplus
#include "Exception.h"
+#endif
#include "SEService.h"
#include "Reader.h"
#include "Session.h"
Name: smartcard-service
Description: Make flags of Common library of Smartcard service
Version: 1.0
-Requires: dlog
+Requires: glib-2.0 dlog
Libs: -L${libdir} -lsmartcard-service
-Cflags: -I${includedir}/smartcard-service
+Cflags: -I${includedir}/smartcard-service
\ No newline at end of file
/* SLP library header */
/* local header */
+#include "smartcard-types.h"
#include "Debug.h"
#include "APDUHelper.h"
namespace smartcard_service_api
{
/* ResponseHelper class */
- ResponseHelper::ResponseHelper()
- : status(0)
+ ResponseHelper::ResponseHelper() : status(0)
{
}
bool ResponseHelper::setResponse(const ByteArray &response)
{
bool result = false;
- status = 0;
- dataField.releaseBuffer();
+ status = SCARD_ERROR_UNKNOWN;
+ dataField.clear();
this->response = response;
- if (response.getLength() >= 2)
+ if (response.size() >= 2)
{
- sw[0] = response.getReverseAt(1);
- sw[1] = response.getReverseAt(0);
+ sw[0] = response.reverseAt(1);
+ sw[1] = response.reverseAt(0);
status = parseStatusWord(sw);
- if (response.getLength() > 2)
+ if (response.size() > 2)
{
- dataField.setBuffer(response.getBuffer(),
- response.getLength() - 2);
+ dataField.assign(response.getBuffer(),
+ response.size() - 2);
}
result = true;
return result;
}
- int ResponseHelper::parseStatusWord(unsigned char *sw)
+ int ResponseHelper::parseStatusWord(const unsigned char *sw)
{
int result = sw[0] << 8 | sw[1];
case (unsigned char)0x90 : /* SW2:00, No further qualification */
case (unsigned char)0x91 : /* extra information */
case (unsigned char)0x92 : /* extra information */
- result = 0;
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;
+
+#if 0
+ case (unsigned char)0x61 : /* SW2 encodes the number of data bytes still available */
+ 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;
+#endif
default :
result *= -1;
break;
return result;
}
- int ResponseHelper::getStatus()
- {
- return status;
- }
-
int ResponseHelper::getStatus(const ByteArray &response)
{
int status = 0;
- if (response.getLength() >= 2)
+ if (response.size() >= 2)
{
- status = ResponseHelper::parseStatusWord(response.getBuffer((response.getLength() - 2)));
+ status = ResponseHelper::parseStatusWord(response.getBuffer((response.size() - 2)));
}
return status;
}
- unsigned char ResponseHelper::getSW1()
- {
- return sw[0];
- }
-
- unsigned char ResponseHelper::getSW2()
- {
- return sw[1];
- }
-
- ByteArray ResponseHelper::getDataField()
- {
- return dataField;
- }
-
- ByteArray ResponseHelper::getDataField(const ByteArray &response)
+ const ByteArray ResponseHelper::getDataField(const ByteArray &response)
{
ByteArray result;
- if (response.getLength() > 2)
+ if (response.size() > 2)
{
- result.setBuffer(response.getBuffer(), response.getLength() - 2);
+ result.assign(response.getBuffer(), response.size() - 2);
}
return result;
{
}
- bool APDUCommand::setCommand(unsigned char cla, unsigned char ins, unsigned char p1,
- unsigned char p2, ByteArray commandData, unsigned int maxResponseSize)
+ bool APDUCommand::setCommand(unsigned char cla, unsigned char ins,
+ unsigned char p1, unsigned char p2,
+ const ByteArray &commandData,
+ unsigned int maxResponseSize)
{
setCLA(cla);
setINS(ins);
uint32_t offset = 0;
uint32_t lengthSize = 1;
- if (command.getLength() < sizeof(header))
+ if (command.size() < sizeof(header))
{
return false;
}
lengthSize = 2;
}
- if (command.getLength() - offset > lengthSize)
+ if (command.size() - offset > lengthSize)
{
unsigned int length = 0;
}
else
{
- length = command.getAt(offset);
+ length = command.at(offset);
+ if (length == 0) {
+ length = 256;
+ }
offset += 1;
}
offset += length;
}
- if (command.getLength() - offset == lengthSize)
+ if (command.size() - offset == lengthSize)
{
if (isExtendedLength)
{
unsigned int temp;
- temp = command.getAt(offset) << 8;
- temp |= command.getAt(offset + 1);
+ temp = command.at(offset) << 8;
+ temp |= command.at(offset + 1);
if (temp == 0)
setMaxResponseSize(APDUCommand::LE_MAX);
}
else
{
- if (command.getAt(offset) == 0)
- setMaxResponseSize(APDUCommand::LE_MAX);
+ if (command.at(offset) == 0)
+ setMaxResponseSize(256);
else
- setMaxResponseSize(command.getAt(offset));
+ setMaxResponseSize(command.at(offset));
offset += 1;
}
}
- if (command.getLength() == offset)
+ if (command.size() == offset)
{
result = true;
}
else
{
- SCARD_DEBUG_ERR("command stream is not correct, command.getLength() [%d], offset [%d]", command.getLength(), offset);
+ _ERR("command stream is not correct, command.size() [%d], offset [%d]", command.size(), offset);
}
return result;
{
case INS_TERMINAL_PROFILE :
case INS_FETCH :
- case INS_ENVELOPE :
case INS_TERMINAL_RESPONSE :
result = true;
break;
header.cla = cla;
}
- unsigned char APDUCommand::getCLA()
+ unsigned char APDUCommand::getCLA() const
{
return header.cla;
}
header.ins = ins;
}
- unsigned char APDUCommand::getINS()
+ unsigned char APDUCommand::getINS() const
{
return header.ins;
}
header.param[0] = p1;
}
- unsigned char APDUCommand::getP1()
+ unsigned char APDUCommand::getP1() const
{
return header.param[0];
}
header.param[1] = p2;
}
- unsigned char APDUCommand::getP2()
+ unsigned char APDUCommand::getP2() const
{
return header.param[1];
}
commandData = data;
}
- ByteArray APDUCommand::getCommandData()
+ const ByteArray APDUCommand::getCommandData() const
{
return commandData;
}
this->maxResponseSize = maxResponseSize;
}
- unsigned int APDUCommand::getMaxResponseSize()
+ unsigned int APDUCommand::getMaxResponseSize() const
{
return maxResponseSize;
}
- bool APDUCommand::getBuffer(ByteArray &array)
+ bool APDUCommand::getBuffer(ByteArray &array) const
{
unsigned char *temp_buffer = NULL;
unsigned int temp_len = 0;
temp_len += sizeof(header);
/* calculate lc length */
- if (commandData.getLength() > 0)
+ if (commandData.size() > 0)
{
- if (isExtendedLength/*commandData.getLength() > 255*/)
+ if (isExtendedLength/*commandData.size() > 255*/)
{
- lc[1] = (commandData.getLength() >> 8) & 0x000000FF;
- lc[2] = commandData.getLength() & 0x000000FF;
+ lc[1] = (commandData.size() >> 8) & 0x000000FF;
+ lc[2] = commandData.size() & 0x000000FF;
lc_len = 3;
}
else
{
- lc[0] = commandData.getLength() & 0x000000FF;
+ lc[0] = commandData.size() & 0x000000FF;
lc_len = 1;
}
temp_len += lc_len;
/* add command data length */
- temp_len += commandData.getLength();
+ temp_len += commandData.size();
/* calculate le length */
if (maxResponseSize > 0)
{
- if (isExtendedLength/*commandData.getLength() > 255*/)
+ if (isExtendedLength/*commandData.size() > 255*/)
{
if (maxResponseSize < 65536)
{
memcpy(temp_buffer + offset, &header, sizeof(header));
offset += sizeof(header);
- if (commandData.getLength() > 0)
+ if (commandData.size() > 0)
{
memcpy(temp_buffer + offset, &lc, lc_len);
offset += lc_len;
- memcpy(temp_buffer + offset, commandData.getBuffer(), commandData.getLength());
- offset += commandData.getLength();
+ memcpy(temp_buffer + offset, commandData.getBuffer(), commandData.size());
+ offset += commandData.size();
}
if (maxResponseSize > 0)
offset += le_len;
}
- array.setBuffer(temp_buffer, temp_len);
+ array.assign(temp_buffer, temp_len);
delete []temp_buffer;
return true;
}
/* APDUHelper class */
- ByteArray APDUHelper::generateAPDU(int command, int channel, ByteArray data)
+ const ByteArray APDUHelper::generateAPDU(int command,
+ int channel, const ByteArray &data)
{
ByteArray result;
APDUCommand apdu;
switch (command)
{
case COMMAND_OPEN_LOGICAL_CHANNEL :
- apdu.setCommand(0, APDUCommand::INS_MANAGE_CHANNEL, 0, 0, ByteArray::EMPTY, APDUCommand::LE_MAX);
+ apdu.setCommand(0, APDUCommand::INS_MANAGE_CHANNEL, 0, 0, ByteArray::EMPTY, 1);
apdu.getBuffer(result);
break;
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.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_DF_NAME, APDUCommand::P2_SELECT_GET_FCI, data, 0);
apdu.getBuffer(result);
break;
/* local header */
#include "Debug.h"
#include "SimpleTLV.h"
+#include "AccessControlList.h"
#include "AccessCondition.h"
namespace smartcard_service_api
{
- void APDUAccessRule::loadAPDUAccessRule(const ByteArray &data)
+ void AccessRule::addAPDUAccessRule(const ByteArray &apdu,
+ const ByteArray &mask)
{
- SimpleTLV tlv(data);
+ pair<ByteArray, ByteArray> item(apdu, mask);
- if (tlv.decodeTLV() == true)
- {
- switch (tlv.getTag())
- {
- case 0xA0 : /* CHOICE 0 : APDUPermission */
- permission = SimpleTLV::getBoolean(tlv.getValue());
- break;
-
- case 0xA1 : /* CHOICE 1 : APDUFilters */
- tlv.enterToValueTLV();
- while (tlv.decodeTLV() == true)
- {
- if (tlv.getTag() == 0x04) /* OCTET STRING */
- {
- ByteArray apdu, mask, value;
-
- value = tlv.getValue();
-
- 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;
- }
- }
+ listFilters.push_back(item);
}
- bool APDUAccessRule::isAuthorizedAccess(const ByteArray &command)
+ bool AccessRule::isAuthorizedAPDUAccess(const ByteArray &command) const
{
bool result = false;
- if (mapApduFilters.size() > 0)
+ if (command.size() < 4) /* apdu header size */
+ return false;
+
+ if (listFilters.size() > 0)
{
- /* TODO : search command and check validity */
+ unsigned int cmd, mask, rule;
+ vector<pair<ByteArray, ByteArray> >::const_iterator item;
+
+ cmd = *(unsigned int *)command.getBuffer();
+ for (item = listFilters.begin(); item != listFilters.end(); item++)
+ {
+ mask = *(unsigned int *)item->second.getBuffer();
+ rule = *(unsigned int *)item->first.getBuffer();
+
+ if ((cmd & mask) == rule)
+ {
+ result = true;
+ break;
+ }
+ }
}
else
{
/* no filter entry. if permission is true, all access will be granted, if not, all access will be denied */
- result = permission;
+ result = apduRule;
}
return result;
}
- void APDUAccessRule::printAPDUAccessRules()
+ void AccessRule::printAccessRules() const
{
- SCARD_DEBUG(" +-- APDU Access Rule");
-
- if (mapApduFilters.size() > 0)
+ if (listFilters.size() > 0)
{
- map<ByteArray, ByteArray>::iterator iterMap;
+ vector<pair<ByteArray, ByteArray> >::const_iterator item;
- for (iterMap = mapApduFilters.begin(); iterMap != mapApduFilters.end(); iterMap++)
+ _DBG(" +---- Granted APDUs");
+
+ for (item = listFilters.begin(); item != listFilters.end(); item++)
{
- SCARD_DEBUG(" +--- APDU : %s, Mask : %s", ((ByteArray)(iterMap->first)).toString(), iterMap->second.toString());
+ _DBG(" +----- APDU : %s, Mask : %s", item->first.toString().c_str(), item->second.toString().c_str());
}
}
else
{
- SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ _DBG(" +---- APDU Access ALLOW : %s", apduRule ? "ALWAYS" : "NEVER");
}
+
+ _DBG(" +---- NFC Access ALLOW : %s", nfcRule ? "ALWAYS" : "NEVER");
}
- void NFCAccessRule::loadNFCAccessRule(const ByteArray &data)
+ bool AccessRule::isAuthorizedNFCAccess(void) const
{
- permission = SimpleTLV::getBoolean(data);
+ return nfcRule;
}
- bool NFCAccessRule::isAuthorizedAccess(void)
+ AccessRule *AccessCondition::getAccessRule(const ByteArray &certHash)
{
- bool result = false;
+ AccessRule *result = NULL;
+ map<ByteArray, AccessRule>::iterator item;
- result = permission;
+ item = mapRules.find(certHash);
+ if (item != mapRules.end()) {
+ result = &item->second;
+ }
return result;
}
- void NFCAccessRule::printNFCAccessRules()
+ const AccessRule *AccessCondition::getAccessRule(const ByteArray &certHash) const
{
- SCARD_DEBUG(" +-- NFC Access Rule");
- SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ const AccessRule *result = NULL;
+ map<ByteArray, AccessRule>::const_iterator item;
+
+ item = mapRules.find(certHash);
+ if (item != mapRules.end()) {
+ result = &item->second;
+ }
+
+ return result;
}
- void AccessCondition::loadAccessCondition(ByteArray &aid, ByteArray &data)
+ void AccessCondition::addAccessRule(const ByteArray &hash)
{
- if (data.getLength() > 0)
- {
- SimpleTLV tlv(data);
+ AccessRule rule;
- 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());
+ pair<ByteArray, AccessRule> item(hash, rule);
- permission = true;
- break;
- }
- }
- }
- else
- {
- SCARD_DEBUG("access denied for all applications, aid : %s", aid.toString());
+ mapRules.insert(item);
+ }
- permission = false;
+ void AccessCondition::setAccessCondition(bool rule)
+ {
+ AccessRule *result;
+
+ result = getAccessRule(AccessControlList::ALL_DEVICE_APPS);
+ if (result == NULL) {
+ addAccessRule(AccessControlList::ALL_DEVICE_APPS);
+ result = getAccessRule(AccessControlList::ALL_DEVICE_APPS);
+ if (result == NULL)
+ return;
}
+
+ result->setAPDUAccessRule(rule);
+ result->setNFCAccessRule(rule);
}
- bool AccessCondition::isAuthorizedAccess(ByteArray &certHash)
+ bool AccessCondition::isAuthorizedAccess(const ByteArray &certHash) const
{
bool result = false;
+ const AccessRule *rule = getAccessRule(certHash);
- if (hashes.size() > 0)
+ if (rule != NULL) {
+ result = rule->isAuthorizedAccess();
+ }
+
+ return result;
+ }
+
+ void AccessCondition::printAccessConditions() const
+ {
+ _DBG(" +-- Access Condition");
+
+ if (mapRules.size() > 0)
{
- size_t i;
+ map<ByteArray, AccessRule>::const_iterator item;
- for (i = 0; i < hashes.size(); i++)
+ for (item = mapRules.begin(); item != mapRules.end(); item++)
{
- if (certHash == hashes[i])
- {
- result = true;
- break;
- }
+ ByteArray temp = item->first;
+
+ _DBG(" +--- hash : %s", (temp == AccessControlList::ALL_DEVICE_APPS) ? "All device applications" : temp.toString().c_str());
+ item->second.printAccessRules();
}
}
else
{
- result = permission;
+ _DBG(" +--- no rule found");
}
+ }
- return result;
+ void AccessCondition::setAPDUAccessRule(const ByteArray &certHash,
+ bool rule)
+ {
+ AccessRule *access = getAccessRule(certHash);
+
+ if (access != NULL) {
+ access->setAPDUAccessRule(rule);
+ }
}
- bool AccessCondition::isAuthorizedAPDUAccess(ByteArray &command)
+ void AccessCondition::addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &apdu, const ByteArray &mask)
{
- bool result = false;
+ AccessRule *access = getAccessRule(certHash);
- result = apduRule.isAuthorizedAccess(command);
+ if (access != NULL) {
+ access->addAPDUAccessRule(apdu, mask);
+ }
+ }
- return result;
+ void AccessCondition::addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &rule)
+ {
+ if (rule.size() != 8)
+ return;
+
+ addAPDUAccessRule(certHash, rule.sub(0, 4), rule.sub(4, 4));
+ }
+
+ void AccessCondition::setNFCAccessRule(const ByteArray &certHash,
+ bool rule)
+ {
+ AccessRule *access = getAccessRule(certHash);
+
+ if (access != NULL) {
+ access->setNFCAccessRule(rule);
+ }
}
- bool AccessCondition::isAuthorizedNFCAccess()
+ bool AccessCondition::isAuthorizedAPDUAccess(const ByteArray &certHash,
+ const ByteArray &command) const
{
bool result = false;
+ const AccessRule *rule = getAccessRule(certHash);
- result = nfcRule.isAuthorizedAccess();
+ if (rule != NULL) {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
return result;
}
- void AccessCondition::printAccessConditions()
+ bool AccessCondition::isAuthorizedNFCAccess(const ByteArray &certHash) const
{
- SCARD_DEBUG(" +-- Access Condition");
-
- if (hashes.size() > 0)
- {
- size_t i;
+ bool result = false;
+ const AccessRule *rule = getAccessRule(certHash);
- for (i = 0; i < hashes.size(); i++)
- {
- SCARD_DEBUG(" +--- hash : %s", hashes[i].toString());
- }
- }
- else
- {
- SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
}
+
+ return result;
}
} /* namespace smartcard_service_api */
#include "Debug.h"
#include "AccessControlList.h"
#include "PKCS15.h"
-#include "AccessCondition.h"
namespace smartcard_service_api
{
- const unsigned char aid_all[] = { 0x00, 0x00 };
- const unsigned char aid_default[] = { 0x00, 0x01 };
+ const unsigned char all_se_apps[] = { 0x00, 0x00 };
+ const unsigned char default_se_app[] = { 0x00, 0x01 };
+ const unsigned char all_device_apps[] = { 0x00, 0x02 };
- ByteArray AccessControlList::AID_ALL(ARRAY_AND_SIZE(aid_all));
- ByteArray AccessControlList::AID_DEFAULT(ARRAY_AND_SIZE(aid_default));
+ ByteArray AccessControlList::ALL_SE_APPS(ARRAY_AND_SIZE(all_se_apps));
+ ByteArray AccessControlList::DEFAULT_SE_APP(ARRAY_AND_SIZE(default_se_app));
+ ByteArray AccessControlList::ALL_DEVICE_APPS(ARRAY_AND_SIZE(all_device_apps));
- AccessControlList::AccessControlList()
+ AccessControlList::AccessControlList() : allGranted(false)
{
- allGranted = false;
}
AccessControlList::~AccessControlList()
allGranted = false;
}
- bool AccessControlList::isAuthorizedAccess(ByteArray aid, ByteArray certHash, bool update)
+ AccessCondition &AccessControlList::getAccessCondition(const ByteArray &aid)
{
- bool result = allGranted;
- map<ByteArray, AccessCondition>::iterator iterMap;
+ map<ByteArray, AccessCondition>::iterator item;
- if (result == false)
+ item = mapConditions.find(aid);
+ if (item == mapConditions.end())
{
- SCARD_DEBUG("aid : %s", aid.toString());
- SCARD_DEBUG("hash : %s", certHash.toString());
+ AccessCondition condition;
+ pair<ByteArray, AccessCondition> temp(aid, condition);
+ mapConditions.insert(temp);
- /* null aid means default applet */
- if (aid.isEmpty() == true)
- {
- aid = AID_DEFAULT;
- }
+ item = mapConditions.find(aid);
+ }
- /* first.. find hashes matched with aid */
- if ((iterMap = mapConditions.find(aid)) != mapConditions.end())
- {
- result = iterMap->second.isAuthorizedAccess(certHash);
- }
- /* finally.. find hashes in 'all' list */
- else if ((iterMap = mapConditions.find(AID_ALL)) != mapConditions.end())
- {
- result = iterMap->second.isAuthorizedAccess(certHash);
- }
+ return item->second;
+ }
+
+ const AccessRule *AccessControlList::findAccessRule(const ByteArray &aid,
+ const ByteArray &hash) const
+ {
+ const AccessRule *result = NULL;
+ map<ByteArray, AccessCondition>::const_iterator item;
+
+ item = mapConditions.find(aid);
+ if (item != mapConditions.end()) {
+ result = item->second.getAccessRule(hash);
}
return result;
}
- bool AccessControlList::isAuthorizedAccess(ByteArray aid, ByteArray certHash)
+ bool AccessControlList::isAuthorizedAccess(const ByteArray &aid,
+ const ByteArray &certHash) const
+ {
+ vector<ByteArray> hashes;
+
+ hashes.push_back(certHash);
+
+ return isAuthorizedAccess(aid, hashes);
+ }
+
+ bool AccessControlList::isAuthorizedAccess(const unsigned char *aidBuffer,
+ unsigned int aidLength, const unsigned char *certHashBuffer,
+ unsigned int certHashLength) const
{
- return isAuthorizedAccess(aid, certHash, true);
+ ByteArray aid(aidBuffer, aidLength);
+ ByteArray certHash(certHashBuffer, certHashLength);
+
+ return isAuthorizedAccess(aid, certHash);
}
- bool AccessControlList::isAuthorizedAccess(unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength)
+ bool AccessControlList::isAuthorizedAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const
{
- return isAuthorizedAccess(ByteArray(aidBuffer, aidLength), ByteArray(certHashBuffer, certHashLength), true);
+ return isAuthorizedAccess(aid, certHashes, ByteArray::EMPTY);
}
- bool AccessControlList::isAuthorizedAccess(ByteArray aid, vector<ByteArray> &certHashes)
+ bool AccessControlList::isAuthorizedAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes, const ByteArray &command) const
{
- bool result;
+ bool result = allGranted;
+ vector<ByteArray>::const_reverse_iterator item;
+ const AccessRule *rule = NULL;
+
+ if (result == true) {
+ goto END;
+ }
+
+ /* Step A, find with aid and cert hashes */
+ for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
+ rule = findAccessRule(aid, *item);
+ if (rule != NULL) {
+ if (command.isEmpty()) {
+ result = rule->isAuthorizedAccess();
+ } else {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), (*item).toString().c_str());
+ goto END;
+ }
+ }
+
+ /* Step B, find with aid and ALL_DEVICES_APPS */
+ rule = findAccessRule(aid, ALL_DEVICE_APPS);
+ if (rule != NULL) {
+ if (command.isEmpty()) {
+ result = rule->isAuthorizedAccess();
+ } else {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), ALL_DEVICE_APPS.toString().c_str());
+ goto END;
+ }
+
+ /* Step C, find with ALL_SE_APPS and hashes */
+ for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
+ rule = findAccessRule(ALL_SE_APPS, *item);
+ if (rule != NULL) {
+ if (command.isEmpty()) {
+ result = rule->isAuthorizedAccess();
+ } else {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString().c_str());
+ goto END;
+ }
+ }
+
+ /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
+ rule = findAccessRule(ALL_SE_APPS, ALL_DEVICE_APPS);
+ if (rule != NULL) {
+ if (command.isEmpty()) {
+ result = rule->isAuthorizedAccess();
+ } else {
+ result = rule->isAuthorizedAPDUAccess(command);
+ }
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
+ goto END;
+ }
+
size_t i;
- result = allGranted;
+ _INFO("no rule found, aid [%s]", aid.toString().c_str());
- if (result == false)
- {
- for (i = 0; result == false && i < certHashes.size(); i++)
- {
- result = isAuthorizedAccess(aid, certHashes[i], false);
+ for (i = 0; i < certHashes.size(); i++) {
+ _INFO(" hash[%d] [%s]", i, certHashes[i].toString().c_str());
+ }
+
+END :
+ return result;
+ }
+
+ bool AccessControlList::isAuthorizedNFCAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const
+ {
+ bool result = allGranted;
+ vector<ByteArray>::const_reverse_iterator item;
+ const AccessRule *rule = NULL;
+
+ if (result == true) {
+ goto END;
+ }
+
+ /* Step A, find with aid and cert hashes */
+ for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
+ rule = findAccessRule(aid, *item);
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), (*item).toString().c_str());
+ goto END;
}
}
+ /* Step B, find with aid and ALL_DEVICES_APPS */
+ rule = findAccessRule(aid, ALL_DEVICE_APPS);
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), "All device applications");
+ goto END;
+ }
+
+ /* Step C, find with ALL_SE_APPS and hashes */
+ for (item = certHashes.rbegin(); item != certHashes.rend(); item++) {
+ rule = findAccessRule(ALL_SE_APPS, *item);
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString().c_str());
+ goto END;
+ }
+ }
+
+ /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
+ rule = findAccessRule(ALL_SE_APPS, ALL_DEVICE_APPS);
+ if (rule != NULL) {
+ result = rule->isAuthorizedNFCAccess();
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
+ goto END;
+ }
+
+ size_t i;
+
+ _INFO("no rule found, aid [%s]", aid.toString().c_str());
+
+ for (i = 0; i < certHashes.size(); i++) {
+ _INFO(" hash[%d] [%s]", i, certHashes[i].toString().c_str());
+ }
+END :
return result;
}
- void AccessControlList::printAccessControlList()
+ void AccessControlList::printAccessControlList() const
{
ByteArray temp;
+ map<ByteArray, AccessCondition>::const_iterator iterMap;
- /* release map and vector */
- map<ByteArray, AccessCondition>::iterator iterMap;
-
- SCARD_DEBUG("================ Certification Hashes ==================");
+ _DBG("========================== Access Control Rules ============================");
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());
+ _DBG("+ aid : %s", (temp == DEFAULT_SE_APP) ? "Default Application" : (temp == ALL_SE_APPS) ? "All SE Applications" : temp.toString().c_str());
iterMap->second.printAccessConditions();
}
- SCARD_DEBUG("========================================================");
+ _DBG("============================================================================");
}
} /* namespace smartcard_service_api */
*/
/* standard library header */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
+#include <cstdio>
+#include <cstring>
+#include <cerrno>
+#include <sstream>
/* SLP library header */
{
ByteArray ByteArray::EMPTY = ByteArray();
- ByteArray::ByteArray()
+ ByteArray::ByteArray() : buffer(NULL), length(0)
{
- buffer = NULL;
- length = 0;
}
- ByteArray::ByteArray(uint8_t *array, uint32_t bufferLen)
+ ByteArray::ByteArray(const uint8_t *array, size_t size) :
+ buffer(NULL), length(0)
{
- buffer = NULL;
- length = 0;
-
- setBuffer(array, bufferLen);
+ assign(array, size);
}
- ByteArray::ByteArray(const ByteArray &T)
+ ByteArray::ByteArray(const ByteArray &T) : buffer(NULL), length(0)
{
- buffer = NULL;
- length = 0;
-
- setBuffer(T.buffer, T.length);
+ assign(T.buffer, T.length);
}
ByteArray::~ByteArray()
{
- releaseBuffer();
+ clear();
}
- bool ByteArray::setBuffer(uint8_t *array, uint32_t bufferLen)
+ bool ByteArray::assign(const uint8_t *array, size_t size)
{
- if (array == NULL || bufferLen == 0)
+ if (array == NULL || size == 0)
{
return false;
}
- releaseBuffer();
+ clear();
- buffer = new uint8_t[bufferLen];
+ buffer = new uint8_t[size];
if (buffer == NULL)
{
- SCARD_DEBUG_ERR("alloc failed");
+ _ERR("alloc failed");
return false;
}
- memcpy(buffer, array, bufferLen);
- length = bufferLen;
+ memcpy(buffer, array, size);
+ length = size;
return true;
}
- bool ByteArray::_setBuffer(uint8_t *array, uint32_t bufferLen)
+ bool ByteArray::_assign(uint8_t *array, size_t size)
{
- if (array == NULL || bufferLen == 0)
+ if (array == NULL || size == 0)
{
return false;
}
- releaseBuffer();
+ clear();
buffer = array;
- length = bufferLen;
+ length = size;
return true;
}
- uint32_t ByteArray::getLength() const
+ size_t ByteArray::size() const
{
return length;
}
- uint8_t *ByteArray::getBuffer() const
+ uint8_t *ByteArray::getBuffer()
+ {
+ return getBuffer(0);
+ }
+
+ const uint8_t *ByteArray::getBuffer() const
{
return getBuffer(0);
}
- uint8_t *ByteArray::getBuffer(uint32_t offset) const
+ uint8_t *ByteArray::getBuffer(size_t offset)
{
if (length == 0)
return NULL;
if (offset >= length)
{
- SCARD_DEBUG_ERR("buffer overflow, offset [%d], length [%d]", offset, length);
+ _ERR("buffer overflow, offset [%d], length [%d]", offset, length);
return NULL;
}
return buffer + offset;
}
- uint8_t ByteArray::getAt(uint32_t index) const
+ const uint8_t *ByteArray::getBuffer(size_t offset) const
+ {
+ if (length == 0)
+ return NULL;
+
+ if (offset >= length)
+ {
+ _ERR("buffer overflow, offset [%d], length [%d]", offset, length);
+ return NULL;
+ }
+
+ return buffer + offset;
+ }
+
+ uint8_t ByteArray::at(size_t index) const
{
if (index >= length)
{
- SCARD_DEBUG_ERR("buffer overflow, index [%d], length [%d]", index, length);
- return buffer[length -1];
+ _ERR("buffer overflow, index [%d], length [%d]", index, length);
+ if (length > 0)
+ {
+ return buffer[length - 1];
+ }
+ else
+ {
+ return 0;
+ }
}
return buffer[index];
}
- uint8_t ByteArray::getReverseAt(uint32_t index) const
+ uint8_t ByteArray::reverseAt(size_t index) const
{
if (index >= length)
{
- SCARD_DEBUG_ERR("buffer underflow, index [%d], length [%d]", index, length);
- return buffer[0];
+ _ERR("buffer underflow, index [%d], length [%d]", index, length);
+ if (length > 0)
+ {
+ return buffer[0];
+ }
+ else
+ {
+ return 0;
+ }
}
return buffer[length - index - 1];
}
- uint32_t ByteArray::copyFromArray(uint8_t *array, uint32_t bufferLen) const
+ size_t ByteArray::extract(uint8_t *array, size_t size) const
{
uint32_t min_len = 0;
- if (array == NULL || bufferLen == 0)
+ if (array == NULL || size == 0)
{
- SCARD_DEBUG_ERR("invaild param");
- return false;
+ _ERR("invalid param");
+ return min_len;
}
- min_len = (bufferLen < length) ? bufferLen : length;
+ min_len = (size < length) ? size : length;
memcpy(array, buffer, min_len);
return min_len;
}
- void ByteArray::releaseBuffer()
+ const ByteArray ByteArray::sub(size_t offset, size_t size) const
+ {
+ if (length == 0 || offset >= length || (offset + size) > length)
+ {
+ _DBG("length is zero");
+
+ return ByteArray();
+ }
+
+ return ByteArray(buffer + offset, size);
+ }
+
+ void ByteArray::clear()
{
if (buffer != NULL)
{
/* operator overloading */
ByteArray ByteArray::operator +(const ByteArray &T)
{
- uint32_t newLen;
+ size_t newLen;
uint8_t *newBuffer;
ByteArray newArray;
if (length == 0)
{
- SCARD_DEBUG("length is zero");
+ _DBG("length is zero");
return T;
}
if (newBuffer == NULL)
{
/* assert.... */
- SCARD_DEBUG_ERR("alloc failed");
+ _ERR("alloc failed");
return *this;
}
memcpy(newBuffer, buffer, length);
memcpy(newBuffer + length, T.buffer, T.length);
- newArray._setBuffer(newBuffer, newLen);
+ newArray._assign(newBuffer, newLen);
return newArray;
}
{
if (this != &T)
{
- setBuffer(T.buffer, T.length);
+ assign(T.buffer, T.length);
}
return *this;
return (memcmp(buffer, T.buffer, (length < T.length) ? length : T.length) > 0);
}
- uint8_t &ByteArray::operator [](uint32_t index) const
+ uint8_t ByteArray::operator [](size_t index) const
{
if (index >= length)
{
- SCARD_DEBUG_ERR("buffer overflow, index [%d], length [%d]", index, length);
- return buffer[length -1];
+ _ERR("buffer overflow, index [%d], length [%d]", index, length);
+ if (length > 0)
+ {
+ return buffer[length -1];
+ }
+ else
+ {
+ return 0;
+ }
}
return buffer[index];
}
- const char *ByteArray::toString()
+ const string ByteArray::toString() const
{
- memset(strBuffer, 0, sizeof(strBuffer));
+#ifdef TO_STRING_ALL
+ return toString(true);
+#else
+ return toString(false);
+#endif
+ }
- if (length == 0)
- {
- snprintf(strBuffer, sizeof(strBuffer), "buffer is empty");
- }
- else
+ const string ByteArray::toString(bool entire) const
+ {
+ stringstream ss;
+
+ if (length > 0)
{
+ char temp[20];
int count;
- int i, offset = 0;
+ int i = 0;
bool ellipsis = false;
count = length;
- if (count > 20)
+ if (entire == false && count > 20)
{
count = 20;
ellipsis = true;
}
- snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "{ ");
- offset += 2;
+ ss << "{ ";
for (i = 0; i < count; i++)
{
- snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "%02X ", buffer[i]);
- offset += 3;
+ snprintf(temp, sizeof(temp), "%02X ", buffer[i]);
+ ss << temp;
}
if (ellipsis)
{
- snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "... }");
- }
- else
- {
- snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "}");
+ ss << "... ";
}
+
+ ss << "}";
+ }
+ else
+ {
+ ss << "buffer is empty";
}
- return (const char *)strBuffer;
+ return ss.str();
}
void ByteArray::save(const char *filePath)
{
fwrite(buffer, 1, length, file);
fflush(file);
-
fclose(file);
- SCARD_DEBUG("file has written, file [%s], length[%d]", filePath, length);
+
+ SECURE_LOGD("file has written, file [%s], length[%d]", filePath, length);
}
else
{
- SCARD_DEBUG_ERR("file open failed, [%d]", errno);
+ _ERR("file open failed, [%d]", errno);
}
}
} /* namespace smartcard_service_api */
-
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SRCS)
#IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
-# SET(CMAKE_BUILD_TYPE "Debug")
+# 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 aul libssl pkgmgr pkgmgr-info)
+pkg_check_modules(pkgs_common REQUIRED glib-2.0 gio-unix-2.0 dlog aul libssl pkgmgr pkgmgr-info)
MESSAGE("${LIB_NAME} ld flag : ${pkgs_common_LDFLAGS}")
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 "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -finstrument-functions")
#SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
#SET(CMAKE_C_FLAGS_RELEASE "-O2")
-#SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -finstrument-functions -std=c++0x")
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -finstrument-functions -std=c++0x")
#SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
#SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
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")
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_common_LDFLAGS})
SET(EXPORT_HEADER
+ include/smartcard-types.h
include/Debug.h
include/Exception.h
include/ByteArray.h
include/TerminalInterface.h
include/Terminal.h
include/SignatureHelper.h
- include/GPSEACL.h
)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
FOREACH(hfile ${EXPORT_HEADER})
- INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
+ INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
ENDFOREACH(hfile)
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* standard library header */
-#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)
- {
- DispatcherMsg *pushMsg = new DispatcherMsg(msg);
-
- syncLock();
-
- messageQ.push(pushMsg);
-
- signalCondition();
- syncUnlock();
- }
-
- void *DispatcherHelper::_dispatcherThreadFunc(void *data)
- {
- int result = 0;
- DispatcherMsg *msg = NULL;
- DispatcherHelper *helper = (DispatcherHelper *)data;
-
- while (1)
- {
- helper->syncLock();
- if ((msg = helper->fetchMessage()) == NULL)
- {
- result = helper->waitTimedCondition(0);
- helper->syncUnlock();
- continue;
- }
- helper->syncUnlock();
-
- /* process message */
- helper->dispatcherThreadFunc(msg, data);
-
- delete msg;
- }
-
- return (void *)NULL;
- }
-
- void DispatcherHelper::processMessage(DispatcherMsg *msg)
- {
- dispatcherThreadFunc(msg, this);
- }
-
- 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 */
namespace smartcard_service_api
{
+ static unsigned char path_efdir[] = { 0x2f, 0x00 };
+ static ByteArray PATH_EFDIR(ARRAY_AND_SIZE(path_efdir));
+
EFDIR::EFDIR(Channel *channel) : FileObject(channel)
{
- unsigned char path[] = { 0x2f, 0x00 };
- ByteArray dirPath(ARRAY_AND_SIZE(path));
- int ret;
-
- ret = select(dirPath, false);
- if (ret == FileObject::SUCCESS)
- {
- SCARD_DEBUG("response : %s", selectResponse.toString());
- }
- else
- {
- SCARD_DEBUG_ERR("EFDIR select failed, [%d]", ret);
- }
}
- EFDIR::EFDIR(Channel *channel, ByteArray selectResponse)
- : FileObject(channel, selectResponse)
+ EFDIR::EFDIR(Channel *channel, const ByteArray &selectResponse) :
+ FileObject(channel, selectResponse)
{
}
{
}
- ByteArray EFDIR::parseRecord(Record &record, ByteArray &aid)
+ int EFDIR::select()
+ {
+ int ret;
+
+ ret = FileObject::select(PATH_EFDIR, false);
+ if (ret < SCARD_ERROR_OK)
+ {
+ _ERR("EFDIR select failed, [%d]", ret);
+ }
+
+ return ret;
+ }
+
+ const ByteArray EFDIR::parseRecord(const Record &record, const ByteArray &aid)
{
bool matched = false;
ByteArray result;
if (matched == true)
{
- SCARD_DEBUG("Found!! : path %s", result.toString());
+ _DBG("Found!! : path %s", result.toString().c_str());
}
else
{
- result.setBuffer(NULL, 0);
+ result.clear();
}
}
return result;
}
- ByteArray EFDIR::getPathByAID(ByteArray &aid)
+ const ByteArray EFDIR::getPathByAID(const ByteArray &aid)
{
ByteArray result;
Record record;
if (status >= 0)
{
result = parseRecord(record, aid);
- if (result.getLength() > 0)
+ if (result.size() > 0)
break;
}
}
*/
/* standard library header */
-#include <stdio.h>
-#include <string.h>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
/* SLP library header */
resetMemberVar();
}
- FCP::FCP(ByteArray &array)
+ FCP::FCP(const ByteArray &array)
{
resetMemberVar();
lcs = FCI::INFO_NOT_AVAILABLE;
}
- bool FCP::setFCP(ByteArray array)
+ bool FCP::setFCP(const ByteArray &array)
{
bool result = false;
SimpleTLV tlv;
- SCARD_BEGIN();
+ _BEGIN();
releaseFCP();
- if (array.getLength() == 0)
+ if (array.size() == 0)
return false;
fcpBuffer = array;
if (fcpBuffer[0] != 0x62)
{
- SCARD_DEBUG_ERR("it is not FCP response [%02X]", fcpBuffer[0]);
+ _ERR("it is not FCP response [%02X]", fcpBuffer[0]);
return false;
}
/* parse... */
- tlv.setTLVBuffer(fcpBuffer.getBuffer(), fcpBuffer.getLength());
+ tlv.setTLVBuffer(fcpBuffer);
if (tlv.decodeTLV())
{
{
switch (tlv.getTag())
{
- case 0x80 : /* file length without sturctural inforamtion */
+ case 0x80 : /* file length without structural information */
{
- SCARD_DEBUG("0x%02X : file length without sturctural inforamtion : %s", tlv.getTag(), tlv.getValue().toString());
- if (tlv.getLength() > 0)
+ _DBG("0x%02X : file length without structural information : %s", tlv.getTag(), tlv.getValue().toString().c_str());
+ if (tlv.size() > 0)
{
fileSize = NumberStream::getBigEndianNumber(tlv.getValue());
}
}
break;
- case 0x81 : /* file length with sturctural inforamtion */
+ case 0x81 : /* file length with structural information */
{
- SCARD_DEBUG("0x%02X : file length with sturctural inforamtion : %s", tlv.getTag(), tlv.getValue().toString());
- if (tlv.getLength() > 0)
+ _DBG("0x%02X : file length with structural information : %s", tlv.getTag(), tlv.getValue().toString().c_str());
+ if (tlv.size() > 0)
{
maxRecordSize = NumberStream::getBigEndianNumber(tlv.getValue());
}
case 0x82 : /* file descriptor bytes */
{
- SCARD_DEBUG("0x%02X : file descriptor bytes : %s", tlv.getTag(), tlv.getValue().toString());
+ _DBG("0x%02X : file descriptor bytes : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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)
+ _DBG("0x%02X : file identifier : %s", tlv.getTag(), tlv.getValue().toString().c_str());
+ if (tlv.size() > 0)
{
ByteArray value = tlv.getValue();
fid = 0;
- memcpy(&fid, value.getBuffer(), value.getLength());
+ memcpy(&fid, value.getBuffer(), value.size());
}
}
break;
case 0x84 : /* DF name */
{
- SCARD_DEBUG("0x%02X : DF name : %s", tlv.getTag(), tlv.getValue().toString());
+ SECURE_LOGD("0x%02X : DF name : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ _DBG("0x%02X : proprietary information not encoded in BER-TLV : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ SECURE_LOGD("0x%02X : Security attribute in proprietary format : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ _DBG("0x%02X : Identifier of an EF containing an extension of the file control information : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// ByteArray value = tlv.getValue();
}
break;
case 0x88 : /* Short EF identifier */
{
- SCARD_DEBUG("0x%02X : Short EF identifier : %s", tlv.getTag(), tlv.getValue().toString());
+ _DBG("0x%02X : Short EF identifier : %s", tlv.getTag(), tlv.getValue().toString().c_str());
- if (tlv.getLength() > 0)
+ if (tlv.size() > 0)
{
ByteArray value = tlv.getValue();
sfi = 0;
- memcpy(&sfi, value.getBuffer(), value.getLength());
+ memcpy(&sfi, value.getBuffer(), value.size());
}
}
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)
+ _DBG("0x%02X : life cycle status byte : %s", tlv.getTag(), tlv.getValue().toString().c_str());
+ if (tlv.size() > 0)
{
ByteArray value = tlv.getValue();
lcs = 0;
- memcpy(&lcs, value.getBuffer(), value.getLength());
+ memcpy(&lcs, value.getBuffer(), value.size());
}
}
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());
+ SECURE_LOGD("0x%02X : Security attribute referencing the expanded format : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ SECURE_LOGD("0x%02X : Security attribute in compact format : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ SECURE_LOGD("0x%02X : Identifier of an EF containing security environment templates : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// ByteArray value = tlv.getValue();
}
break;
case 0x8E : /* Channel security attribute */
{
- SCARD_DEBUG("0x%02X : Channel security attribute : %s", tlv.getTag(), tlv.getValue().toString());
+ SECURE_LOGD("0x%02X : Channel security attribute : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ SECURE_LOGD("0x%02X : Security attribute template for data objects : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ SECURE_LOGD("0x%02X : Security attribute template in proprietary format : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ _DBG("0x%02X : Template consisting of one or more pairs of data objects : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ _DBG("0x%02X : proprietary information encoded in BER-TLV : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ SECURE_LOGD("0x%02X : Security attribute template in expanded format : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ _DBG("0x%02X : Cryptographic mechanism identifier template : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// 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());
+ SECURE_LOGD("0x%02X : PIN status template DO : %s", tlv.getTag(), tlv.getValue().toString().c_str());
// ByteArray value = tlv.getValue();
}
break;
default :
{
- SCARD_DEBUG("0x%02X : unknown : %s", tlv.getTag(), tlv.getValue().toString());
+ _DBG("0x%02X : unknown : %s", tlv.getTag(), tlv.getValue().toString().c_str());
}
break;
}
}
else
{
- SCARD_DEBUG_ERR("tlv.decodeTLV failed");
+ _ERR("tlv.decodeTLV failed");
}
- SCARD_END();
+ _END();
return result;
}
- ByteArray FCP::getFCP()
+ const ByteArray FCP::getFCP() const
{
return fcpBuffer;
}
void FCP::releaseFCP()
{
- fcpBuffer.releaseBuffer();
+ fcpBuffer.clear();
resetMemberVar();
}
- unsigned int FCP::getFileSize()
+ int FCP::getFileSize() const
{
return fileSize;
}
- unsigned int FCP::getTotalFileSize()
+ int FCP::getTotalFileSize() const
{
return totalFileSize;
}
- unsigned int FCP::getFID()
+ int FCP::getFID() const
{
return fid;
}
- unsigned int FCP::getSFI()
+ int FCP::getSFI() const
{
return sfi;
}
- unsigned int FCP::getMaxRecordSize()
+ int FCP::getMaxRecordSize() const
{
return maxRecordSize;
}
- unsigned int FCP::getNumberOfRecord()
+ int FCP::getNumberOfRecord() const
{
return numberOfRecord;
}
- unsigned int FCP::getFileType()
+ int FCP::getFileType() const
{
return fileType;
}
- unsigned int FCP::getFileStructure()
+ int FCP::getFileStructure() const
{
return fileStructure;
}
- unsigned int FCP::getLCS()
+ int FCP::getLCS() const
{
return lcs;
}
- const char *FCP::toString()
+ const string FCP::toString() const
{
- memset(strBuffer, 0, sizeof(strBuffer));
+ stringstream ss;
- 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());
+ if (fileSize != FCI::INFO_NOT_AVAILABLE)
+ ss << "size [" << fileSize << "], ";
- return (const char *)strBuffer;
+ if (totalFileSize != FCI::INFO_NOT_AVAILABLE)
+ ss << "total size [" << totalFileSize << "], ";
+
+ if (fid != FCI::INFO_NOT_AVAILABLE)
+ ss << "fid [" << fid << "], ";
+
+ if (sfi != FCI::INFO_NOT_AVAILABLE)
+ ss << "sfi [" << sfi << "], ";
+
+ if (maxRecordSize != FCI::INFO_NOT_AVAILABLE)
+ ss << "max rec. [" << maxRecordSize << "], ";
+
+ if (numberOfRecord != FCI::INFO_NOT_AVAILABLE)
+ ss << "n of rec [" << numberOfRecord << "], ";
+
+ if (fileType != FCI::INFO_NOT_AVAILABLE)
+ ss << "type [" << fileType << "], ";
+
+ if (fileStructure != FCI::INFO_NOT_AVAILABLE)
+ ss << "struct [" << fileStructure << "], ";
+
+ if (lcs != FCI::INFO_NOT_AVAILABLE)
+ ss << "lcs [" << lcs << "], ";
+
+ return ss.str();
}
{
}
- bool FCI::setFCIBuffer(ByteArray array)
+ bool FCI::setFCIBuffer(const ByteArray &array)
{
bool result = false;
/* standard library header */
#include <stdio.h>
+#include <glib.h>
/* SLP library header */
opened = false;
}
- FileObject::FileObject(Channel *channel, ByteArray selectResponse)
+ FileObject::FileObject(Channel *channel, const ByteArray &selectResponse)
: ProviderHelper(channel)
{
opened = false;
void FileObject::close()
{
opened = false;
- selectResponse.releaseBuffer();
+ selectResponse.clear();
}
- bool FileObject::setSelectResponse(ByteArray &response)
+ bool FileObject::setSelectResponse(const ByteArray &response)
{
bool result = false;
- if (response.getLength() >= 2)
+ if (response.size() >= 2)
{
ResponseHelper resp(response);
selectResponse = response;
- if (resp.getStatus() == 0)
+ if (resp.getStatus() >= 0)
{
fcp.releaseFCP();
fcp.setFCP(resp.getDataField());
- SCARD_DEBUG("FCP : %s", fcp.toString());
+ _DBG("FCP : %s", fcp.toString().c_str());
opened = true;
result = true;
}
else
{
- SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]",
- resp.getStatus(), resp.getSW1(), resp.getSW2());
+ _ERR("status word [ %02X %02X ]",
+ resp.getSW1(), resp.getSW2());
}
}
else
{
- SCARD_DEBUG_ERR("invalid response : %s", response.toString());
+ _ERR("invalid response");
}
return result;
}
- int FileObject::_select(ByteArray command)
+ int FileObject::_select(const ByteArray &command)
{
int ret = ERROR_ILLEGAL_STATE;
ByteArray result;
if (channel == NULL || channel->isClosed())
{
- SCARD_DEBUG_ERR("channel is not open");
+ _ERR("channel is not open");
return ret;
}
{
ResponseHelper resp(result);
- if (resp.getStatus() == 0)
- {
- if (setSelectResponse(result) == true)
- {
- opened = true;
- ret = SUCCESS;
- }
- else
- {
- ret = ERROR_ILLEGAL_STATE;
- }
- }
- else if (resp.getStatus() == ResponseHelper::ERROR_FILE_NOT_FOUND)
- {
- ret = ResponseHelper::ERROR_FILE_NOT_FOUND;
- }
+ ret = resp.getStatus();
+
+ setSelectResponse(result);
}
else
{
- SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]",
- ret, result.getLength());
+ _ERR("select apdu is failed, rv [%d], length [%d]",
+ ret, result.size());
ret = ERROR_ILLEGAL_STATE;
}
return ret;
}
- int FileObject::select(ByteArray aid)
+ int FileObject::select(const ByteArray &aid)
{
int ret = ERROR_ILLEGAL_STATE;
ByteArray command;
return ret;
}
- int FileObject::select(ByteArray path, bool fromCurrentDF)
+ int FileObject::select(const ByteArray &path, bool fromCurrentDF)
{
int ret = ERROR_ILLEGAL_STATE;
ByteArray command;
{
ByteArray temp(path);
- if (path.getLength() > 2 && path[0] == 0x3f && path[1] == 0x00) /* check MF */
+ if (path.size() > 2 && path[0] == 0x3f && path[1] == 0x00) /* check MF */
{
/* remove MF from path */
- temp.setBuffer(path.getBuffer(2), path.getLength() - 2);
+ temp.assign(path.getBuffer(2), path.size() - 2);
}
command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH, 0, temp);
return ret;
}
- FCI *FileObject::getFCI()
+ const FCI *FileObject::getFCI() const
{
return NULL;
}
- FCP *FileObject::getFCP()
+ const FCP *FileObject::getFCP() const
{
return &fcp;
}
apdu.getBuffer(command);
ret = channel->transmitSync(command, response);
- if (ret == 0 && response.getLength() >= 2)
+ if (ret == 0 && response.size() >= 2)
{
ResponseHelper resp(response);
ret = resp.getStatus();
- if (ret == 0)
+ if (ret >= 0)
{
- SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString());
+ _DBG("response [%d] : %s", response.size(), response.toString().c_str());
result = Record(recordId, resp.getDataField());
}
else
{
- SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
+ _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
}
}
else
{
- SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, response.getLength());
+ _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
}
return ret;
}
- int FileObject::writeRecord(unsigned int sfi, Record record)
+ int FileObject::writeRecord(unsigned int sfi, const Record &record)
{
return 0;
}
- int FileObject::searchRecord(unsigned int sfi, ByteArray searchParam, vector<int> &result)
+ int FileObject::searchRecord(unsigned int sfi, const ByteArray &searchParam, vector<int> &result)
{
return 0;
}
+#define MAX_SINGLE_LEN 256
+
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);
+ /* FIXME : fix calculating length */
+ apdu.setCommand(0, APDUCommand::INS_READ_BINARY,
+ (offset >> 8) & 0x7F, offset & 0x00FF,
+ ByteArray::EMPTY, (length > MAX_SINGLE_LEN - 1) ? 0 : length);
+
apdu.getBuffer(command);
ret = channel->transmitSync(command, response);
- if (ret == 0 && response.getLength() >= 2)
+ if (ret == 0 && response.size() >= 2)
{
ResponseHelper resp(response);
- if (resp.getStatus() == 0)
+ if (resp.getStatus() >= 0)
{
- SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString());
+ _DBG("response [%d] : %s", response.size(), response.toString().c_str());
result = resp.getDataField();
}
else
{
- SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
+ _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
}
}
else
{
- SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, response.getLength());
+ _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
}
return ret;
}
- int FileObject::writeBinary(unsigned int sfi, ByteArray data, unsigned int offset, unsigned int length)
+ int FileObject::readBinary(unsigned int sfi, unsigned int length, ByteArray &result)
+ {
+ int ret;
+ size_t offset = 0;
+ ByteArray temp;
+
+ do {
+ ret = readBinary(sfi, offset, length - offset, temp);
+ if (ret >= SCARD_ERROR_OK) {
+ result += temp;
+ offset += temp.size();
+ }
+ } while (ret >= SCARD_ERROR_OK && offset < length);
+
+ return ret;
+ }
+
+ int FileObject::writeBinary(unsigned int sfi, const ByteArray &data, unsigned int offset, unsigned int length)
{
ByteArray command, response;
APDUCommand apdu;
apdu.getBuffer(command);
ret = channel->transmitSync(command, response);
- if (ret == 0 && response.getLength() >= 2)
+ if (ret == 0 && response.size() >= 2)
{
ResponseHelper resp(response);
- if (resp.getStatus() == 0)
+ if (resp.getStatus() >= 0)
{
- SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString());
+ _DBG("response [%d] : %s", response.size(), response.toString().c_str());
ret = SUCCESS;
}
else
{
- SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
+ _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
}
}
else
{
- SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, response.getLength());
+ _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
}
return ret;
}
+
+ int FileObject::writeBinary(unsigned int sfi, const ByteArray &data)
+ {
+ int result;
+ size_t offset = 0, len;
+ ByteArray temp;
+
+ do {
+ len = MIN(data.size() - offset, MAX_SINGLE_LEN);
+ temp.setBuffer(data.getBuffer(offset), len);
+ result = writeBinary(sfi, temp, offset, len);
+ if (result >= SCARD_ERROR_OK) {
+ offset += len;
+ }
+ } while (result >= SCARD_ERROR_OK && offset < data.size());
+
+ return result;
+ }
+
+ int FileObject::readBinaryAll(unsigned int sfi, ByteArray &result)
+ {
+ int ret;
+
+ ret = readBinary(sfi, getFCP()->getFileSize(), result);
+
+ return ret;
+ }
+
} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GDBusHelper.h"
+
+namespace smartcard_service_api
+{
+ void GDBusHelper::convertVariantToByteArray(GVariant *var,
+ ByteArray &array)
+ {
+ GVariantIter *iter;
+ guint8 element;
+ guint8 *buf = NULL;
+ guint size = 0;
+ guint i;
+
+ g_variant_get(var, "a(y)", &iter);
+
+ size = g_variant_iter_n_children(iter);
+ buf = g_new0(guint8, size);
+
+ for (i = 0; g_variant_iter_loop(iter, "(y)", &element); i++)
+ {
+ buf[i] = element;
+ }
+
+ g_variant_iter_free(iter);
+
+ array.assign((uint8_t *)buf, (uint32_t)i);
+
+ g_free(buf);
+ }
+
+ GVariant *GDBusHelper::convertByteArrayToVariant(const ByteArray &array)
+ {
+ GVariantBuilder builder;
+ uint32_t i;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("a(y)"));
+
+ for (i = 0; i < array.size(); i++)
+ g_variant_builder_add(&builder, "(y)", array[i]);
+
+ return g_variant_builder_end(&builder);
+ }
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "GPACE.h"
+#include "GPARAACL.h"
+#include "GPARFACL.h"
+#include "SessionHelper.h"
+#include "ReaderHelper.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ GPACE::GPACE() : AccessControlList(), acl(NULL)
+ {
+ }
+
+ GPACE::~GPACE()
+ {
+ if (acl != NULL) {
+ delete acl;
+ }
+ }
+
+ int GPACE::loadACL(Channel *channel)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (channel == NULL)
+ {
+ return SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ if (acl == NULL) {
+ /* first, check ara-m */
+ GPARAACL *araACL = new GPARAACL;
+
+ result = araACL->loadACL(channel);
+ if (result < SCARD_ERROR_OK) {
+ _ERR("ARA not found");
+
+ delete araACL;
+
+ if (true) {
+ _INFO("try to use ARF");
+ /* second, check arf when channel is for SIM */
+ GPARFACL *arfACL = new GPARFACL;
+
+ result = arfACL->loadACL(channel);
+ if (result >= SCARD_ERROR_OK) {
+ acl = arfACL;
+ } else {
+ delete arfACL;
+ }
+ }
+ } else {
+ acl = araACL;
+ }
+ } else {
+ result = acl->loadACL(channel);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ bool GPACE::isAuthorizedAccess(const ByteArray &aid,
+ const ByteArray &certHash) const
+ {
+ return (acl != NULL) ? acl->isAuthorizedAccess(aid, certHash) : false;
+ }
+
+ bool GPACE::isAuthorizedAccess(const unsigned char *aidBuffer,
+ unsigned int aidLength, const unsigned char *certHashBuffer,
+ unsigned int certHashLength) const
+ {
+ return (acl != NULL) ? acl->isAuthorizedAccess(aidBuffer, aidLength, certHashBuffer, certHashLength) : false;
+ }
+
+ bool GPACE::isAuthorizedAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const
+ {
+ return (acl != NULL) ? acl->isAuthorizedAccess(aid, certHashes) : false;
+ }
+
+ bool GPACE::isAuthorizedAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes,
+ const ByteArray &command) const
+ {
+ return (acl != NULL) ? acl->isAuthorizedAccess(aid, certHashes, command) : false;
+ }
+
+ bool GPACE::isAuthorizedNFCAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const
+ {
+ return (acl != NULL) ? acl->isAuthorizedNFCAccess(aid, certHashes) : false;
+ }
+
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "GPARAACL.h"
+#include "GPARAM.h"
+#include "NumberStream.h"
+#include "SimpleTLV.h"
+#include "ISO7816BERTLV.h"
+#include "AccessCondition.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ static unsigned char aid_aram[] = { 0xA0, 0x00, 0x00, 0x01, 0x51, 0x41, 0x43, 0x4C, 0x00 };
+ static ByteArray AID_ARAM(ARRAY_AND_SIZE(aid_aram));
+
+#define GET_DATA_ALL 0
+#define GET_DATA_SPECIFIC 1
+#define GET_DATA_REFRESH_TAG 2
+#define GET_DATA_NEXT 3
+
+#define ARAM_TAG_ALL_AR 0x0000FF40
+#define ARAM_TAG_AR 0x0000FF50
+#define ARAM_TAG_REFRESH 0x0000DF20
+
+#define DO_TAG_AID_REF 0x0000004F
+#define DO_TAG_AID_REF_DEFAULT 0x000000C0
+#define DO_TAG_HASH_REF 0x000000C1
+#define DO_TAG_APDU_AR 0x000000D0
+#define DO_TAG_NFC_AR 0x000000D1
+#define DO_TAG_REF 0x000000E1
+#define DO_TAG_REF_AR 0x000000E2
+#define DO_TAG_AR 0x000000E3
+
+ GPARAACL::GPARAACL() : AccessControlList()
+ {
+ }
+
+ GPARAACL::~GPARAACL()
+ {
+ }
+
+ static ByteArray getAID(SimpleTLV &tlv)
+ {
+ ByteArray result;
+
+ _BEGIN();
+
+ if (tlv.decodeTLV() == true) {
+ switch (tlv.getTag()) {
+ case DO_TAG_AID_REF :
+ if (tlv.size() > 0) {
+ result = tlv.getValue();
+ } else {
+ result = AccessControlList::ALL_SE_APPS;
+ }
+ break;
+
+ case DO_TAG_AID_REF_DEFAULT :
+ result = AccessControlList::DEFAULT_SE_APP;
+ break;
+
+ default :
+ _ERR("decodeTLV failed, %s", tlv.toString().c_str());
+ break;
+ }
+ } else {
+ _ERR("decodeTLV failed, %s", tlv.toString().c_str());
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static ByteArray getHash(SimpleTLV &tlv)
+ {
+ ByteArray result;
+
+ _BEGIN();
+
+ if (tlv.decodeTLV() == true &&
+ tlv.getTag() == DO_TAG_HASH_REF) {
+ if (tlv.size() > 0) {
+ result = tlv.getValue();
+ } else {
+ result = AccessControlList::ALL_DEVICE_APPS;
+ }
+ } else {
+ _ERR("decodeTLV failed, %s", tlv.toString().c_str());
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static int parseRefDO(SimpleTLV &tlv, ByteArray &aid, ByteArray &hash)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == DO_TAG_REF) {
+ tlv.enterToValueTLV();
+ aid = getAID(tlv);
+ hash = getHash(tlv);
+ tlv.returnToParentTLV();
+
+ _DBG("aid : %s, hash : %s", aid.toString().c_str(), hash.toString().c_str());
+ } else {
+ _ERR("unknown tag : %s", tlv.toString().c_str());
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static int parseARDO(SimpleTLV &tlv, vector<ByteArray> &apduRule,
+ ByteArray &nfcRule)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == DO_TAG_AR) {
+ tlv.enterToValueTLV();
+ while (tlv.decodeTLV() == true) {
+ int length = tlv.size();
+
+ switch (tlv.getTag()) {
+ case DO_TAG_APDU_AR :
+ if (length > 1) {
+ int i;
+ ByteArray temp;
+
+ for (i = 0; i < length; i += 8) {
+ temp.assign(tlv.getValue().getBuffer(i), 8);
+ _DBG("apdu rule[%d] : %s", temp.size(), temp.toString().c_str());
+ apduRule.push_back(temp);
+ }
+ } else if (length == 1){
+ _DBG("apdu rule : %s", tlv.getValue().toString().c_str());
+ apduRule.push_back(tlv.getValue());
+ } else {
+ _ERR("invalid rule, %s", tlv.toString().c_str());
+ }
+ break;
+
+ case DO_TAG_NFC_AR :
+ nfcRule = tlv.getValue();
+ _DBG("nfc rule : %s", tlv.getValue().toString().c_str());
+ break;
+
+ default :
+ break;
+ }
+ }
+ tlv.returnToParentTLV();
+ } else {
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ _END();
+
+ return result;
+ }
+
+ void GPARAACL::addCondition(const ByteArray &aid, const ByteArray &hash,
+ const vector<ByteArray> &apduRule, const ByteArray &nfcRule)
+ {
+ AccessCondition &condition = getAccessCondition(aid);
+
+ _BEGIN();
+
+ condition.addAccessRule(hash);
+
+ if (apduRule.size() > 0) {
+ if (apduRule.size() == 1 &&
+ apduRule[0].size() == 1) {
+ /* apdu grant/deny */
+ if (apduRule[0][0] == 1) {
+ condition.setAPDUAccessRule(hash, true);
+ } else {
+ condition.setAPDUAccessRule(hash, false);
+ }
+ } else {
+ size_t i;
+
+ for (i = 0; i < apduRule.size(); i++) {
+ condition.addAPDUAccessRule(hash, apduRule[i]);
+ }
+ }
+ }
+
+ if (nfcRule.size() == 1) {
+ if (nfcRule[0] == 1) {
+ condition.setNFCAccessRule(hash, true);
+ } else {
+ condition.setNFCAccessRule(hash, false);
+ }
+ }
+
+ _END();
+ }
+
+ int GPARAACL::updateRule(const ByteArray &data)
+ {
+ int result = SCARD_ERROR_OK;
+ SimpleTLV tlv(data);
+
+ _BEGIN();
+
+ while (tlv.decodeTLV() == true) {
+ if (tlv.getTag() == DO_TAG_REF_AR) {
+ ByteArray aid, hash, nfcRule;
+ vector<ByteArray> apduRule;
+
+ tlv.enterToValueTLV();
+ result = parseRefDO(tlv, aid, hash);
+
+ if (result >= SCARD_ERROR_OK) {
+ result = parseARDO(tlv, apduRule, nfcRule);
+ }
+ tlv.returnToParentTLV();
+
+ addCondition(aid, hash, apduRule, nfcRule);
+ } else {
+ _ERR("unknown tag, [%x]", tlv.getTag());
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ break;
+ }
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int GPARAACL::loadACL(GPARAM &aram)
+ {
+ int result = SCARD_ERROR_OK;
+ ByteArray refreshTag, response;
+
+ _BEGIN();
+
+ if (aram.isClosed() == true) {
+ return SCARD_ERROR_ILLEGAL_STATE;
+ }
+
+ /* get refresh tag */
+ result = aram.getDataRefreshTag(refreshTag);
+ if (result >= SCARD_ERROR_OK) {
+ /* check refresh tag */
+ if (this->refreshTag.isEmpty() == true ||
+ this->refreshTag != refreshTag) {
+ result = aram.getDataAll(response);
+ if (result >= SCARD_ERROR_OK) {
+ result = updateRule(response);
+
+ /* update refresh tag */
+ this->refreshTag = refreshTag;
+ } else {
+ _ERR("getDataAll failed, [%x]", result);
+ }
+ }
+ else
+ {
+ _INFO("access rules are not changed. skip update");
+ }
+
+ printAccessControlList();
+ } else {
+ _ERR("transmitSync failed, %x", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int GPARAACL::loadACL(Channel *channel)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (channel == NULL) {
+ return SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ GPARAM aram(channel);
+
+ result = aram.select();
+ if (result >= SCARD_ERROR_OK) {
+ result = loadACL(aram);
+ } else {
+ _ERR("select failed, [%x]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static bool _isAuthorizedAccess(const ByteArray &data, const ByteArray &command)
+ {
+ vector<ByteArray> apduRule;
+ ByteArray nfcRule;
+ SimpleTLV tlv(data);
+ bool result = false;
+
+ if (parseARDO(tlv, apduRule, nfcRule) >= SCARD_ERROR_OK) {
+ if (apduRule.size() > 0) {
+ if (apduRule.size() > 1 ||
+ apduRule[0].size() != 1) {
+ if (command.size() > 0) {
+ /* TODO : check apdu rule */
+ } else {
+ /* check hash only */
+ result = true;
+ }
+ } else {
+ result = (apduRule[0][0] == 1 ? true : false);
+ }
+ } else {
+ _ERR("unknown data : %s", tlv.toString().c_str());
+ }
+ } else {
+ _ERR("parseARDO failed : %s", tlv.toString().c_str());
+ }
+
+ return result;
+ }
+
+ static bool _isAuthorizedNFCAccess(const ByteArray &data)
+ {
+ vector<ByteArray> apduRule;
+ ByteArray nfcRule;
+ SimpleTLV tlv(data);
+ bool result = false;
+
+ if (parseARDO(tlv, apduRule, nfcRule) >= SCARD_ERROR_OK) {
+ if (nfcRule.size() == 1) {
+ result = (nfcRule[0] == 1 ? true : false);
+ } else {
+ _ERR("unknown data : %s", nfcRule.toString().c_str());
+ }
+ } else {
+ _ERR("parseARDO failed : %s", tlv.toString().c_str());
+ }
+
+ return result;
+ }
+
+ bool GPARAACL::isAuthorizedAccess(GPARAM &aram, const ByteArray &aid,
+ const ByteArray &certHash) const
+ {
+ vector<ByteArray> hashes;
+
+ hashes.push_back(certHash);
+
+ return isAuthorizedAccess(aram, aid, hashes, ByteArray::EMPTY);
+ }
+
+ bool GPARAACL::isAuthorizedAccess(GPARAM &aram,
+ const unsigned char *aidBuffer,
+ unsigned int aidLength,
+ const unsigned char *certHashBuffer,
+ unsigned int certHashLength) const
+ {
+ ByteArray aid(aidBuffer, aidLength);
+ ByteArray hash(certHashBuffer, certHashLength);
+
+ return isAuthorizedAccess(aram, aid, hash);
+ }
+
+ bool GPARAACL::isAuthorizedAccess(GPARAM &aram, const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const
+ {
+ return isAuthorizedAccess(aram, aid, certHashes, ByteArray::EMPTY);
+ }
+
+ bool GPARAACL::isAuthorizedAccess(GPARAM &aram, const ByteArray &aid,
+ const vector<ByteArray> &certHashes, const ByteArray &command) const
+ {
+ bool result = allGranted;
+ ByteArray data;
+ vector<ByteArray>::const_reverse_iterator item;
+
+ if (aram.isClosed() == true)
+ return result;
+
+ _BEGIN();
+
+ if (result == true) {
+ goto END;
+ }
+ /* Step A, find with aid and cert hashes */
+ for (item = certHashes.rbegin();
+ result == false && item != certHashes.rend();
+ item++) {
+ if (aram.getDataSpecific(aid, *item, data)
+ >= SCARD_ERROR_OK && data.size() > 0) {
+ result = _isAuthorizedAccess(data, command);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), (*item).toString().c_str());
+ goto END;
+ }
+ }
+
+ /* Step B, find with aid and ALL_DEVICES_APPS */
+ if (aram.getDataSpecific(aid, ByteArray::EMPTY, data)
+ >= SCARD_ERROR_OK && data.size() > 0) {
+ result = _isAuthorizedAccess(data, command);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), "All device applications");
+ goto END;
+ }
+
+ /* Step C, find with ALL_SE_APPS and hashes */
+ for (item = certHashes.rbegin();
+ result == false && item != certHashes.rend();
+ item++) {
+ if (aram.getDataSpecific(ByteArray::EMPTY, *item, data)
+ >= SCARD_ERROR_OK && data.size() > 0) {
+ result = _isAuthorizedAccess(data, command);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString().c_str());
+ goto END;
+ }
+ }
+
+ /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
+ if (aram.getDataSpecific(ByteArray::EMPTY, ByteArray::EMPTY, data)
+ >= SCARD_ERROR_OK && data.size() > 0) {
+ result = _isAuthorizedAccess(data, command);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
+ goto END;
+ }
+
+ END :
+ _END();
+
+ return result;
+ }
+
+ bool GPARAACL::isAuthorizedNFCAccess(GPARAM &aram, const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const
+ {
+ bool result = allGranted;
+ ByteArray data;
+ vector<ByteArray>::const_reverse_iterator item;
+
+ if (aram.isClosed() == true)
+ return result;
+
+ _BEGIN();
+
+ if (result == true) {
+ goto END;
+ }
+ /* Step A, find with aid and cert hashes */
+ for (item = certHashes.rbegin();
+ result == false && item != certHashes.rend();
+ item++) {
+ if (aram.getDataSpecific(aid, *item, data)
+ >= SCARD_ERROR_OK && data.size() > 0) {
+ result = _isAuthorizedNFCAccess(data);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), (*item).toString().c_str());
+ goto END;
+ }
+ }
+
+ /* Step B, find with aid and ALL_DEVICES_APPS */
+ if (aram.getDataSpecific(aid, ByteArray::EMPTY, data)
+ >= SCARD_ERROR_OK && data.size() > 0) {
+ result = _isAuthorizedNFCAccess(data);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", aid.toString().c_str(), "All device applications");
+ goto END;
+ }
+
+ /* Step C, find with ALL_SE_APPS and hashes */
+ for (item = certHashes.rbegin();
+ result == false && item != certHashes.rend();
+ item++) {
+ if (aram.getDataSpecific(ByteArray::EMPTY, *item, data)
+ >= SCARD_ERROR_OK && data.size() > 0) {
+ result = _isAuthorizedNFCAccess(data);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", (*item).toString().c_str());
+ goto END;
+ }
+ }
+
+ /* Step D, find with ALL_SE_APPS and ALL_DEVICES_APPS */
+ if (aram.getDataSpecific(ByteArray::EMPTY, ByteArray::EMPTY, data)
+ >= SCARD_ERROR_OK && data.size() > 0) {
+ result = _isAuthorizedNFCAccess(data);
+ _INFO("rule found (%s): [%s:%s]", result ? "accept" : "deny", "All SE Applications", "All device applications");
+ goto END;
+ }
+
+ END :
+ _END();
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* standard library header */
+#include <glib.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "GPARAM.h"
+#include "APDUHelper.h"
+#include "FileObject.h"
+#include "NumberStream.h"
+#include "SimpleTLV.h"
+#include "ISO7816BERTLV.h"
+#include "AccessCondition.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ static unsigned char aid_aram[] = { 0xA0, 0x00, 0x00, 0x01, 0x51, 0x41, 0x43, 0x4C, 0x00 };
+ static ByteArray AID_ARAM(ARRAY_AND_SIZE(aid_aram));
+
+#define GET_DATA_ALL 0
+#define GET_DATA_SPECIFIC 1
+#define GET_DATA_REFRESH_TAG 2
+#define GET_DATA_NEXT 3
+
+#define ARAM_TAG_ALL_AR 0x0000FF40
+#define ARAM_TAG_AR 0x0000FF50
+#define ARAM_TAG_REFRESH 0x0000DF20
+
+#define DO_TAG_AID_REF 0x0000004F
+#define DO_TAG_AID_REF_DEFAULT 0x000000C0
+#define DO_TAG_HASH_REF 0x000000C1
+#define DO_TAG_APDU_AR 0x000000D0
+#define DO_TAG_NFC_AR 0x000000D1
+#define DO_TAG_REF 0x000000E1
+#define DO_TAG_REF_AR 0x000000E2
+#define DO_TAG_AR 0x000000E3
+
+ GPARAM::GPARAM(Channel *channel)
+ : FileObject(channel)
+ {
+ }
+
+ int GPARAM::select()
+ {
+ return FileObject::select(AID_ARAM);
+ }
+
+ static int doTransmit(Channel *channel, const ByteArray &command, ByteArray &response)
+ {
+ int result;
+ ByteArray resp;
+
+ _BEGIN();
+
+ result = channel->transmitSync(command, resp);
+ if (result == SCARD_ERROR_OK) {
+ result = ResponseHelper::getStatus(resp);
+ if (result >= SCARD_ERROR_OK) {
+ response = ResponseHelper::getDataField(resp);
+ _DBG("response[%d] : %s", response.size(), response.toString().c_str());
+ } else {
+ _ERR("transmit returns error, [%d]", result);
+ }
+ } else {
+ _ERR("transmitSync failed, [%d]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static int doCommand(Channel *channel, int command, ByteArray &response)
+ {
+ int result;
+ APDUCommand helper;
+ ByteArray cmd, resp;
+
+ _BEGIN();
+
+ switch (command) {
+ case GET_DATA_ALL :
+ helper.setCommand(0x80, 0xCA, 0xFF, 0x40, ByteArray::EMPTY, 0);
+ break;
+
+ case GET_DATA_REFRESH_TAG :
+ helper.setCommand(0x80, 0xCA, 0xDF, 0x20, ByteArray::EMPTY, 0);
+ break;
+
+ case GET_DATA_NEXT :
+ helper.setCommand(0x80, 0xCA, 0xFF, 0x60, ByteArray::EMPTY, 0);
+ break;
+ }
+
+ helper.getBuffer(cmd);
+
+ _DBG("command[%d] : %s", cmd.size(), cmd.toString().c_str());
+
+ result = doTransmit(channel, cmd, response);
+
+ _END();
+
+ return result;
+ }
+
+ static int doCommand(Channel *channel, ByteArray &data, ByteArray &response)
+ {
+ int result;
+ APDUCommand helper;
+ ByteArray cmd;
+
+ helper.setCommand(0x80, 0xCA, 0xFF, 0x50, data, 0);
+ helper.getBuffer(cmd);
+
+ result = doTransmit(channel, cmd, response);
+
+ return result;
+ }
+
+ int getLengthAndValue(const ByteArray &data, ByteArray &value)
+ {
+ int result = -1;
+ int offset = 0;
+
+ if (data.isEmpty() == true) {
+ return result;
+ }
+
+ if (data.at(offset) == 0xFF && data.at(offset + 1) == 0x40) {
+ uint8_t count;
+
+ offset += 2;
+ count = data.at(offset);
+
+ offset += 1;
+ if (count & 0x80) {
+ int i;
+
+ count &= ~0x80;
+ result = 0;
+
+ for (i = 0; i < count; i++) {
+ result = (result << 8) | data.at(offset + i);
+ }
+
+ offset += i;
+ } else {
+ result = count;
+ }
+
+ if (result > 0) {
+ value.assign(data.getBuffer(offset),
+ MIN((uint32_t)result,
+ data.size() - offset));
+ }
+ } else {
+ _ERR("invalid tag");
+ }
+
+ return result;
+ }
+
+ int GPARAM::getDataAll(ByteArray &data)
+ {
+ int result;
+ ByteArray response;
+
+ _BEGIN();
+
+ result = doCommand(channel, GET_DATA_ALL, response);
+ if (result >= SCARD_ERROR_OK) {
+ int length;
+
+ length = getLengthAndValue(response, data);
+ if (length > 0){
+ while (length > (int)data.size()) {
+ result = doCommand(channel, GET_DATA_NEXT, response);
+ if (result >= SCARD_ERROR_OK) {
+ data += response;
+ } else {
+ _ERR("generateCommand failed, [%d]", result);
+ data.clear();
+ break;
+ }
+ }
+
+ _DBG("data[%d] : %s", data.size(), data.toString().c_str());
+ } else if (length == 0) {
+ _INFO("Response-ALL-AR-DO is empty");
+ data.clear();
+ } else {
+ _ERR("invalid result, %s", response.toString().c_str());
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+ } else {
+ _ERR("doCommand failed, [%d]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ static int createRefDo(const ByteArray &aid, const ByteArray &hash, ByteArray &refDo)
+ {
+ ByteArray temp;
+
+ temp = SimpleTLV::encode(DO_TAG_AID_REF, aid);
+ temp += SimpleTLV::encode(DO_TAG_HASH_REF, hash);
+
+ refDo = SimpleTLV::encode(DO_TAG_REF, temp);
+ _DBG("encoded Ref DO : %s", refDo.toString().c_str());
+
+ return SCARD_ERROR_OK;
+ }
+
+ int GPARAM::getDataSpecific(const ByteArray &aid, const ByteArray &hash,
+ ByteArray &data)
+ {
+ int result;
+ ByteArray refDo, response;
+
+ _BEGIN();
+
+ createRefDo(aid, hash, refDo);
+
+ result = doCommand(channel, refDo, response);
+ if (result >= SCARD_ERROR_OK) {
+ ISO7816BERTLV tlv(response);
+
+ if (tlv.decodeTLV() == true &&
+ tlv.getTag() == ARAM_TAG_AR) {
+ unsigned int length = tlv.size();
+
+ if (length > 0){
+ data = tlv.getValue();
+
+ while (length > data.size()) {
+ result = doCommand(channel, GET_DATA_NEXT, response);
+ if (result >= SCARD_ERROR_OK) {
+ data += response;
+ } else {
+ _ERR("generateCommand failed, [%d]", result);
+ data.clear();
+ break;
+ }
+ }
+ _DBG("data[%d] : %s", data.size(), data.toString().c_str());
+ } else {
+ _INFO("Response-ALL-AR-DO is empty");
+ data.clear();
+ }
+ } else {
+ _ERR("decodeTLV failed, %s", response.toString().c_str());
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+ } else {
+ _ERR("doCommand failed, [%d]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int GPARAM::getDataRefreshTag(ByteArray &tag)
+ {
+ int result;
+ ByteArray response;
+
+ _BEGIN();
+
+ result = doCommand(channel, GET_DATA_REFRESH_TAG, response);
+ if (result >= SCARD_ERROR_OK) {
+ ISO7816BERTLV tlv(response);
+
+ if (tlv.decodeTLV() == true &&
+ tlv.getTag() == ARAM_TAG_REFRESH &&
+ tlv.size() == 8) {
+ tag = tlv.getValue();
+ result = SCARD_ERROR_OK;
+ _DBG("refreshTag[%d] : %s", tag.size(), tag.toString().c_str());
+ } else {
+ _ERR("decodeTLV failed, %s", response.toString().c_str());
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+ } else {
+ _ERR("generateCommand failed, [%d]", result);
+ }
+
+ _END();
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "GPARFACL.h"
+#include "PKCS15ODF.h"
+#include "PKCS15DODF.h"
+#include "NumberStream.h"
+#include "SimpleTLV.h"
+#include "AccessCondition.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ static unsigned char oid_globalplatform[] = { 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x81, 0x48, 0x01, 0x01 };
+ static ByteArray OID_GLOBALPLATFORM(ARRAY_AND_SIZE(oid_globalplatform));
+
+ GPARFACL::GPARFACL() : AccessControlList()
+ {
+ }
+
+ GPARFACL::~GPARFACL()
+ {
+ }
+
+ int GPARFACL::loadACL(Channel *channel)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (channel == NULL)
+ {
+ return SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ PKCS15 pkcs15(channel);
+
+ /* basically, all requests will be accepted when PKCS #15 doesn't exist or global platform OID is not placed */
+#if 1 /* FOR ORANGE */
+ /* for Orange, every requests will be denied in same cases */
+ allGranted = false;
+#else
+ allGranted = true;
+#endif
+
+ result = pkcs15.select();
+ if (result >= SCARD_ERROR_OK)
+ {
+ PKCS15ODF *odf;
+
+ result = SCARD_ERROR_OK;
+
+ if ((odf = pkcs15.getODF()) != NULL)
+ {
+ PKCS15DODF *dodf;
+
+ if ((dodf = odf->getDODF()) != NULL)
+ {
+ result = loadAccessControl(channel, dodf);
+ if (result == SCARD_ERROR_OK)
+ {
+ printAccessControlList();
+ }
+ else
+ {
+#if 1 /* FOR ORANGE */
+ _ERR("loadAccessControl failed, every request will be denied.");
+#else
+ _INFO("loadAccessControl failed, every request will be accepted.");
+#endif
+ result = SCARD_ERROR_OK;
+ }
+ }
+ else
+ {
+#if 1 /* FOR ORANGE */
+ _ERR("dodf null, every request will be denied.");
+#else
+ _INFO("dodf null, every request will be accepted.");
+#endif
+ }
+ }
+ else
+ {
+#if 1 /* FOR ORANGE */
+ _ERR("odf null, every request will be denied.");
+#else
+ _INFO("odf null, every request will be accepted.");
+#endif
+ }
+ }
+ else
+ {
+#if 1 /* FOR ORANGE */
+ _ERR("failed to open PKCS#15, every request will be denied.");
+#else
+ _INFO("failed to open PKCS#15, every request will be accepted.");
+#endif
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int GPARFACL::loadAccessControl(Channel *channel, PKCS15DODF *dodf)
+ {
+ int result = -1;
+ ByteArray path;
+
+ if ((result = dodf->searchOID(OID_GLOBALPLATFORM, path)) == 0)
+ {
+ ByteArray data;
+ FileObject file(channel);
+
+ _DBG("oid path : %s", path.toString().c_str());
+
+ file.select(NumberStream::getLittleEndianNumber(path));
+ file.readBinaryAll(0, data);
+
+ _DBG("data : %s", data.toString().c_str());
+
+ /* PKCS #15 and DODF OID exists. apply access control rule!! */
+ allGranted = false;
+
+ SimpleTLV tlv(data);
+
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */
+ {
+ tlv.enterToValueTLV();
+
+ /* refresh Tag */
+ ByteArray refreshTag;
+
+ refreshTag = SimpleTLV::getOctetString(tlv);
+ _DBG("current refresh tag : %s", refreshTag.toString().c_str());
+
+ if (this->refreshTag != refreshTag) /* need to update access control list */
+ {
+ this->refreshTag = refreshTag;
+
+ releaseACL();
+
+ /* access control rule path */
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
+ {
+ /* TODO : parse path */
+ ByteArray path;
+
+ /* OCTET STRING */
+ path = SimpleTLV::getOctetString(tlv.getValue());
+ _DBG("access control rule path : %s", path.toString().c_str());
+
+ if (loadRules(channel, path) == 0)
+ {
+ _DBG("loadRules success");
+ }
+ else
+ {
+ _ERR("loadRules failed");
+ }
+ }
+ }
+ else
+ {
+ _INFO("access rules are not changed. skip update");
+ }
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ _ERR("tlv.decodeTLV failed");
+ }
+ }
+ else
+ {
+ _ERR("OID not found");
+ }
+
+ return result;
+ }
+
+ int GPARFACL::loadRules(Channel *channel, const ByteArray &path)
+ {
+ FileObject file(channel);
+ ByteArray data, aid;
+
+ file.select(NumberStream::getLittleEndianNumber(path));
+ file.readBinaryAll(0, data);
+
+ _DBG("data : %s", data.toString().c_str());
+
+ SimpleTLV tlv(data);
+
+ while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Rule */
+ {
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV() == true)
+ {
+ /* target */
+ switch (tlv.getTag())
+ {
+ case 0xA0 : /* CHOICE 0 : EXPLICIT AID */
+ /* OCTET STRING */
+ aid = SimpleTLV::getOctetString(tlv.getValue());
+ break;
+
+ case 0x81 : /* CHOICE 1?? : default */
+ aid = AccessControlList::DEFAULT_SE_APP;
+ break;
+
+ case 0x82 : /* CHOICE 2?? : any application */
+ aid = AccessControlList::ALL_SE_APPS;
+ break;
+ }
+
+ _DBG("aid : %s", aid.toString().c_str());
+
+ /* access condition path */
+ if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
+ {
+ ByteArray path;
+
+ /* OCTET STRING */
+ path = SimpleTLV::getOctetString(tlv.getValue());
+ _DBG("path : %s", path.toString().c_str());
+
+ if (loadAccessConditions(channel, aid, path) == 0)
+ {
+ _DBG("loadCertHashes success");
+ }
+ else
+ {
+ _ERR("loadCertHashes failed");
+ }
+ }
+ else
+ {
+ _ERR("decodeTLV failed");
+ }
+ }
+ else
+ {
+ _ERR("decodeTLV failed");
+ }
+ tlv.returnToParentTLV();
+ }
+
+ return 0;
+ }
+
+ static void loadAPDUAccessRule(AccessRule *rule, const ByteArray &data)
+ {
+ SimpleTLV tlv(data);
+
+ if (rule == NULL) {
+ _ERR("invalid parameter");
+ return;
+ }
+
+ if (tlv.decodeTLV() == true)
+ {
+ switch (tlv.getTag())
+ {
+ case 0xA0 : /* CHOICE 0 : APDUPermission */
+ rule->setAPDUAccessRule(SimpleTLV::getBoolean(tlv.getValue()));
+ break;
+
+ case 0xA1 : /* CHOICE 1 : APDUFilters */
+ tlv.enterToValueTLV();
+ while (tlv.decodeTLV() == true)
+ {
+ if (tlv.getTag() == 0x04) /* OCTET STRING */
+ {
+ ByteArray apdu, mask, value;
+
+ value = tlv.getValue();
+
+ _DBG("APDU rule : %s", value.toString().c_str());
+
+ if (value.size() == 8) /* apdu 4 bytes + mask 4 bytes */
+ {
+ apdu.assign(value.getBuffer(), 4);
+ mask.assign(value.getBuffer(4), 4);
+
+ rule->addAPDUAccessRule(apdu, mask);
+ }
+ else
+ {
+ _ERR("Invalid APDU rule : %s", value.toString().c_str());
+ }
+ }
+ else
+ {
+ _ERR("Unknown tag : 0x%02X", tlv.getTag());
+ }
+ }
+ tlv.returnToParentTLV();
+ break;
+
+ default :
+ _ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+ }
+
+ static void loadNFCAccessRule(AccessRule *rule, const ByteArray &data)
+ {
+ if (rule == NULL) {
+ _ERR("invalid parameter");
+ return;
+ }
+
+ rule->setNFCAccessRule(SimpleTLV::getBoolean(data));
+ }
+
+ static void loadAccessCondition(AccessCondition &condition, const ByteArray &data)
+ {
+ if (data.size() > 0)
+ {
+ SimpleTLV tlv(data);
+ ByteArray hash;
+
+ while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE */
+ {
+ if (tlv.size() > 0)
+ {
+ /* access granted for specific applications */
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV())
+ {
+ switch (tlv.getTag())
+ {
+ case 0x04 : /* OCTET STRING : CertHash */
+ _DBG("aid : %s, hash : %s", condition.getAID().toString().c_str(), tlv.getValue().toString().c_str());
+
+ hash = tlv.getValue();
+ condition.addAccessRule(tlv.getValue());
+ break;
+
+ case 0xA0 : /* CHOICE 0 : AccessRules */
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV())
+ {
+ AccessRule *rule = condition.getAccessRule(hash);
+ if (rule == NULL) {
+ condition.addAccessRule(hash);
+ rule = condition.getAccessRule(hash);
+ }
+
+ switch (tlv.getTag())
+ {
+ case 0xA0 : /* CHOICE 0 : APDUAccessRule */
+ loadAPDUAccessRule(rule, tlv.getValue());
+ break;
+
+ case 0xA1 : /* CHOICE 1 : NFCAccessRule */
+ loadNFCAccessRule(rule, tlv.getValue());
+ break;
+
+ default :
+ _ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+ else
+ {
+ _ERR("tlv.decodeTLV failed");
+ }
+ tlv.returnToParentTLV();
+ break;
+
+ default :
+ _ERR("Unknown tag : 0x%02X", tlv.getTag());
+ break;
+ }
+ }
+ else
+ {
+ _ERR("tlv.decodeTLV failed");
+ }
+ tlv.returnToParentTLV();
+ }
+ else
+ {
+ /* empty rule, it means allow for all application */
+ _INFO("access allowed for all applications, aid : %s", condition.getAID().toString().c_str());
+
+ condition.setAccessCondition(true);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* empty file, it means deny for all application */
+ _INFO("access denied for all applications, aid : %s", condition.getAID().toString().c_str());
+
+ condition.setAccessCondition(false);
+ }
+ }
+
+ int GPARFACL::loadAccessConditions(Channel *channel, const ByteArray &aid, const ByteArray &path)
+ {
+ FileObject file(channel);
+ ByteArray data;
+
+ file.select(NumberStream::getLittleEndianNumber(path));
+ file.readBinaryAll(0, data);
+
+ _DBG("data : %s", data.toString().c_str());
+
+ AccessCondition condition;
+
+ condition.setAID(aid);
+ loadAccessCondition(condition, data);
+
+ pair<ByteArray, AccessCondition> newItem(aid, condition);
+
+ mapConditions.insert(newItem);
+
+ return 0;
+ }
+
+} /* namespace smartcard_service_api */
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* standard library header */
-
-/* SLP library header */
-
-/* local header */
-#include "Debug.h"
-#include "GPSEACL.h"
-#include "PKCS15ODF.h"
-#include "PKCS15DODF.h"
-#include "NumberStream.h"
-#include "SimpleTLV.h"
-#include "AccessCondition.h"
-
-#ifndef EXTERN_API
-#define EXTERN_API __attribute__((visibility("default")))
-#endif
-
-namespace smartcard_service_api
-{
- static unsigned char oid_globalplatform[] = { 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x81, 0x48, 0x01, 0x01 };
- ByteArray GPSEACL::OID_GLOBALPLATFORM(ARRAY_AND_SIZE(oid_globalplatform));
-
- GPSEACL::GPSEACL():AccessControlList()
- {
- }
-
- GPSEACL::~GPSEACL()
- {
- }
-
- int GPSEACL::loadACL(Channel *channel)
- {
- int result = 0;
- PKCS15 *pkcs15;
-
- if (channel == NULL)
- {
- return -1;
- }
-
- pkcs15 = new PKCS15(channel, channel->getSelectResponse());
- if (pkcs15 != NULL)
- {
- /* basically, all requests will be accepted when PKCS #15 doesn't exist or global platform OID is not placed */
- allGranted = true;
-
- if (pkcs15->isClosed() == false)
- {
- PKCS15ODF *odf;
-
- if ((odf = pkcs15->getODF()) != NULL)
- {
- PKCS15DODF *dodf;
-
- if ((dodf = odf->getDODF()) != NULL)
- {
- if (loadAccessControl(channel, dodf) == 0)
- {
- printAccessControlList();
-
- result = 0;
- }
- else
- {
- SCARD_DEBUG_ERR("loadAccessControl failed, every request will be accepted.");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("dodf null, every request will be accepted.");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("odf null, every request will be accepted.");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("failed to open PKCS15, every request will be accepted.");
- }
-
- delete pkcs15;
- }
- else
- {
- return -1;
- }
-
- return result;
- }
-
- int GPSEACL::loadAccessControl(Channel *channel, PKCS15DODF *dodf)
- {
- int result = -1;
- ByteArray path;
-
- if ((result = dodf->searchOID(OID_GLOBALPLATFORM, path)) == 0)
- {
- ByteArray data;
- FileObject file(channel);
-
- 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());
-
- /* PKCS #15 and DODF OID exists. apply access control rule!! */
- allGranted = false;
-
- SimpleTLV tlv(data);
-
- if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */
- {
- tlv.enterToValueTLV();
-
- /* refresh Tag */
- ByteArray refreshTag;
-
- refreshTag = SimpleTLV::getOctetString(tlv);
- 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(channel, 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("OID not found");
- }
-
- return result;
- }
-
- int GPSEACL::loadRules(Channel *channel, ByteArray path)
- {
- FileObject file(channel);
- ByteArray data, aid;
-
- file.select(NumberStream::getLittleEndianNumber(path));
- file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
-
- 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(channel, 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(Channel *channel, 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()
-{
- GPSEACL *acl = new GPSEACL();
-
- return (gp_se_acl_h)acl;
-}
-
-EXTERN_API int gp_se_acl_load_acl(gp_se_acl_h handle, channel_h channel)
-{
- int result = -1;
-
- GP_SE_ACL_EXTERN_BEGIN;
- result = acl->loadACL((Channel *)channel);
- GP_SE_ACL_EXTERN_END;
-
- return result;
-}
-
-EXTERN_API int gp_se_acl_update_acl(gp_se_acl_h handle, channel_h channel)
-{
- int result = -1;
-
- GP_SE_ACL_EXTERN_BEGIN;
- acl->updateACL((Channel *)channel);
- GP_SE_ACL_EXTERN_END;
-
- return result;
-}
-
-EXTERN_API void gp_se_acl_release_acl(gp_se_acl_h handle)
-{
- GP_SE_ACL_EXTERN_BEGIN;
- acl->releaseACL();
- GP_SE_ACL_EXTERN_END;
-}
-
-EXTERN_API bool gp_se_acl_is_authorized_access(gp_se_acl_h handle, unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength)
-{
- bool result = false;
-
- GP_SE_ACL_EXTERN_BEGIN;
- result = acl->isAuthorizedAccess(aidBuffer, aidLength, certHashBuffer, certHashLength);
- GP_SE_ACL_EXTERN_END;
-
- return result;
-}
-
-EXTERN_API void gp_se_acl_destroy_instance(gp_se_acl_h handle)
-{
- GP_SE_ACL_EXTERN_BEGIN;
- delete acl;
- GP_SE_ACL_EXTERN_END;
-}
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* standard library header */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.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>
-#ifdef USE_IPC_EPOLL
-#include <sys/epoll.h>
-#endif
-
-/* SLP library header */
-
-/* local header */
-#include "Debug.h"
-#include "IPCHelper.h"
-
-#ifdef USE_UNIX_DOMAIN
-#define SCARD_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() : fdPoll(-1)
- {
- ipcSocket = -1;
- ioChannel = NULL;
- watchId = 0;
- memset(&ipcLock, 0, sizeof(ipcLock));
- dispatcher = NULL;
- pollEvents = NULL;
- readThread = 0;
- }
-
- 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(SCARD_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, SCARD_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(SCARD_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
- int gid, cookies_size;
- char *cookies;
-
- gid = security_server_get_gid("smartcard-service");
- 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 :
- SCARD_DEBUG_ERR("error while initializing server ipc");
-
- destroyListenSocket();
-
- return false;
- }
-
-#ifdef CLIENT_IPC_THREAD
- int IPCHelper::eventPoll()
- {
- int result = -1;
-
-#ifdef USE_IPC_EPOLL
- int events = 0;
-
- if ((events = epoll_wait(fdPoll, pollEvents, EPOLL_SIZE, -1)) > 0)
- {
- int i;
-
- for (i = 0; i < events; i++)
- {
- SCARD_DEBUG("pollEvents[%d].events [%X]", i, pollEvents[i].events);
-
- if ((pollEvents[i].events & EPOLLHUP) || (pollEvents[i].events & EPOLLERR))
- {
- SCARD_DEBUG_ERR("connection is closed");
- result = 0;
- break;
- }
- else if (pollEvents[i].events & EPOLLIN)
- {
- result = 1;
- break;
- }
- }
- }
- else if (errno == EINTR)
- {
- SCARD_DEBUG_ERR("epoll_wait interrupted");
- }
- else
- {
- char buffer[1024];
-
- SCARD_DEBUG_ERR("epoll_wait failed, errno [%d], %s", errno, strerror_r(errno, buffer, sizeof(buffer)));
- }
-#else
- if (select(ipcSocket + 1, &fdSetRead, NULL, NULL, NULL) > 0)
- {
- if (FD_ISSET(ipcSocket, &fdSetRead) == true)
- {
- int val = -1;
- unsigned int size = sizeof(val);
-
- if (getsockopt(ipcSocket, SOL_SOCKET, SO_ERROR, (void *)&val, &size) == 0)
- {
- if (val == 0)
- {
- SCARD_DEBUG("socket is readable");
- result = 1;
- }
- else
- {
- SCARD_DEBUG("socket is not available. maybe disconnected");
- result = 0;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("getsockopt failed, errno [%d]", errno);
- result = errno;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("FD_ISSET false!!! what's wrong");
- result = -1;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("select failed [%d]", errno);
- result = errno;
- }
-#endif
- return result;
- }
-
- void *IPCHelper::threadRead(void *data)
- {
-#ifdef IPC_USE_SIGTERM
-
- struct sigaction act;
- act.sa_handler = thread_sig_handler;
- sigaction(SIGTERM, &act, NULL);
-
- sigset_t newmask;
- sigemptyset(&newmask);
- sigaddset(&newmask, SIGTERM);
- pthread_sigmask(SIG_UNBLOCK, &newmask, NULL);
- SCARD_DEBUG("sighandler is registered");
-
- pthread_mutex_lock(&g_client_lock);
- pthread_cond_signal ((pthread_cond_t *) data);
- pthread_mutex_unlock(&g_client_lock);
-#else
- IPCHelper *helper = (IPCHelper *)data;
-#endif
- bool condition = true;
- int result = 0;
-
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
-
- while (condition == true)
- {
- if ((result = helper->eventPoll()) > 0)
- {
- condition = (helper->handleIncomingCondition(NULL, G_IO_IN) == 0);
- }
- else if (result == 0)
- {
- helper->handleIOErrorCondition(NULL, G_IO_ERR);
- condition = false;
- }
- else
- {
- /* skip other error case */
- }
- }
-
- SCARD_DEBUG("threadRead is terminated");
-
- return (void *)NULL;
- }
-#endif
-
- bool IPCHelper::createConnectSocket()
- {
-#ifndef CLIENT_IPC_THREAD
- GIOCondition condition = (GIOCondition)(G_IO_ERR | G_IO_HUP | G_IO_IN);
-#endif
- int result = 0;
- char err[200] = { 0, };
-
- 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 [%d, %s]",
- errno, strerror_r(errno, err, sizeof(err)));
- goto ERROR;
- }
-
- SCARD_DEBUG("socket is created");
-
- ::setNonBlockSocket(ipcSocket);
-
- saddrun_rv.sun_family = AF_UNIX;
- strncpy(saddrun_rv.sun_path, SCARD_SERVER_DOMAIN, sizeof(saddrun_rv.sun_path) - 1);
-
- len_saddr = sizeof(saddrun_rv.sun_family) + strlen(SCARD_SERVER_DOMAIN);
-
- if ((result = connect(ipcSocket, (struct sockaddr *)&saddrun_rv, len_saddr)) < 0)
- {
- SCARD_DEBUG_ERR("connect failed [%d, %s]",
- errno, strerror_r(errno, err, sizeof(err)));
- goto ERROR;
- }
-
-#ifdef CLIENT_IPC_THREAD
-#ifdef USE_IPC_EPOLL
- if((fdPoll = epoll_create1(EPOLL_CLOEXEC)) == -1)
- {
- SCARD_DEBUG_ERR("epoll_create1 failed [%d, %s]",
- errno, strerror_r(errno, err, sizeof(err)));
- goto ERROR;
- }
-
- pollEvents = (struct epoll_event *)calloc(EPOLL_SIZE, sizeof(struct epoll_event));
- if (pollEvents == NULL)
- {
- SCARD_DEBUG_ERR("alloc failed");
- goto ERROR;
- }
-
- struct epoll_event ev;
-
- ev.events = EPOLLIN | EPOLLHUP | EPOLLERR;
- ev.data.fd = ipcSocket;
-
- epoll_ctl(fdPoll, EPOLL_CTL_ADD, ipcSocket, &ev);
-#else
- FD_ZERO(&fdSetRead);
- FD_SET(ipcSocket, &fdSetRead);
-#endif
-#ifdef IPC_USE_SIGTERM
- pthread_cond_t pcond = PTHREAD_COND_INITIALIZER;
-
- if (pthread_create(&readThread, NULL, &IPCHelper::threadRead, &pcond) != 0)
-#else
- if (pthread_create(&readThread, NULL, &IPCHelper::threadRead, this) != 0)
-#endif
- {
- SCARD_DEBUG_ERR("pthread_create is failed");
- goto ERROR;
- }
-
-#ifdef IPC_USE_SIGTERM
- pthread_cond_wait (&pcond, &g_client_lock);
-#endif
-
-#else
- 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");
- goto ERROR;
- }
- }
- else
- {
- SCARD_DEBUG_ERR(" g_io_channel_unix_new is failed");
- goto ERROR;
- }
-#endif
- pthread_mutex_unlock(&ipcLock);
-
- SCARD_DEBUG("connecting success");
-
- SCARD_END();
-
- return true;
-
-ERROR :
- SCARD_DEBUG_ERR("error while initializing client ipc");
-
- destroyConnectSocket();
-
- pthread_mutex_unlock(&ipcLock);
-
- SCARD_END();
-
- return false;
- }
-
- void IPCHelper::destroyListenSocket()
- {
- 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;
- }
- }
-
- void IPCHelper::destroyConnectSocket()
- {
-#ifdef CLIENT_IPC_THREAD
- /* kill thread */
- if (readThread > 0)
- {
- pthread_cancel(readThread);
- readThread = 0;
- }
-#ifdef USE_IPC_EPOLL
- if(fdPoll != -1)
- {
- struct epoll_event ev;
-
- ev.events = EPOLLIN | EPOLLHUP | EPOLLERR;
- ev.data.fd = ipcSocket;
- epoll_ctl(fdPoll, EPOLL_CTL_DEL, ipcSocket, &ev);
-
- close(fdPoll);
- fdPoll = -1;
-
- if (pollEvents != NULL)
- {
- free(pollEvents);
- }
- }
-#else
- if (ipcSocket != -1)
- {
- FD_CLR(ipcSocket, &fdSetRead);
- }
-#endif
-#else
- if(watchId != 0)
- {
- g_source_remove(watchId);
- watchId = 0;
- }
-
- if(ioChannel != NULL)
- {
- g_io_channel_unref(ioChannel);
- ioChannel = NULL;
- }
-#endif
-
- if (ipcSocket != -1)
- {
- shutdown(ipcSocket, SHUT_RDWR);
- close(ipcSocket);
- ipcSocket = -1;
- }
- }
-
- bool IPCHelper::sendMessage(int socket, Message *msg)
- {
- ByteArray stream;
- unsigned int length = 0;
-
- stream = msg->serialize();
- length = stream.getLength();
-
- SCARD_DEBUG(">>>[SEND]>>> socket [%d], msg [%d], length [%d]",
- socket, msg->message, stream.getLength());
-
- return sendMessage(socket, stream);
- }
-
- bool IPCHelper::sendMessage(int socket, ByteArray &buffer)
- {
- bool result = false;
- unsigned int length = 0;
-
- length = buffer.getLength();
-
- 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, buffer.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)
- {
- ByteArray buffer;
- Message *msg = NULL;
-
- SCARD_BEGIN();
-
- buffer = retrieveBuffer(socket);
- if (buffer.getLength() > 0)
- {
- msg = new Message();
- if (msg != NULL)
- {
- msg->deserialize(buffer);
- }
- else
- {
- SCARD_DEBUG_ERR("alloc failed");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("retrieveBuffer failed ");
- }
-
- SCARD_END();
-
- return msg;
- }
-
- ByteArray IPCHelper::retrieveBuffer(int socket)
- {
- ByteArray buffer;
- 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)
- {
- uint8_t *temp = NULL;
-
- /* prepare buffer */
- temp = new uint8_t[length];
- if (temp != NULL)
- {
- int retry = 0;
- unsigned int current = 0;
-
- /* read message */
- pthread_mutex_lock(&ipcLock);
- do
- {
- readBytes = recv(socket, temp + current, length - current, 0);
- if (readBytes > 0)
- current += readBytes;
- retry++;
- }
- while (current < length);
- pthread_mutex_unlock(&ipcLock);
-
- SCARD_DEBUG("<<<[RETRIEVE]<<< socket [%d], msg_length [%d]", socket, length);
-
- buffer.setBuffer(temp, length);
-
- delete []temp;
- }
- 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 buffer;
- }
-
- void IPCHelper::setDispatcher(DispatcherHelper *dispatcher)
- {
- this->dispatcher = dispatcher;
- }
-
-} /* namespace smartcard_service_api */
namespace smartcard_service_api
{
- ISO7816BERTLV::ISO7816BERTLV():TLVHelper()
+ ISO7816BERTLV::ISO7816BERTLV() : TLVHelper(), firstByte(0), tagClass(0),
+ encoding(0)
{
- tagClass = 0;
- encoding = 0;
}
- ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent):TLVHelper(parent)
+ ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent) : TLVHelper(parent),
+ firstByte(0), tagClass(0), encoding(0)
{
- parentTLV = parent;
-
- tagClass = 0;
- encoding = 0;
}
- ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array):TLVHelper(array)
+ ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array) : TLVHelper(array),
+ firstByte(0), tagClass(0), encoding(0)
{
- tagClass = 0;
- encoding = 0;
}
- ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent):TLVHelper(array, parent)
+ ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent) :
+ TLVHelper(array, parent), firstByte(0), tagClass(0), encoding(0)
{
- parentTLV = parent;
-
- tagClass = 0;
- encoding = 0;
}
ISO7816BERTLV::~ISO7816BERTLV()
}
}
- int ISO7816BERTLV::decodeTag(unsigned char *buffer)
+ int ISO7816BERTLV::decodeTag(const unsigned char *buffer)
{
/* 0x00 is invalid tag value */
if (buffer[0] == 0x00)
}
/* first byte */
- tagClass = (buffer[0] & 0xE0) >> 6;
+ tagClass = (buffer[0] & 0xC0) >> 6;
encoding = (buffer[0] & 0x20) >> 5;
currentT = buffer[0];
return 2;
}
- int ISO7816BERTLV::decodeLength(unsigned char *buffer)
+ int ISO7816BERTLV::decodeLength(const unsigned char *buffer)
{
- if (buffer[0] & 0x80)
+ uint8_t offset = 0;
+ uint8_t count = buffer[offset];
+
+ offset++;
+
+ if (count & 0x80)
{
- uint8_t count = (buffer[0] & 0x7F);
uint8_t i;
+ count &= ~0x80;
+
/* 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++)
+ for (i = 0; i < count; i++)
{
/* if big endian */
- currentL = (currentL << 8) | buffer[i];
+ currentL = (currentL << 8) | buffer[offset + i];
/* if little endian */
- /* currentL = currentL | (buffer[i] << (8 * (i - 1))); */
+ /* currentL = currentL | (buffer[offset + i] << (8 * (i - 1))); */
}
- return count;
+ offset += i;
}
else
{
- currentL = buffer[0];
-
- return 1;
+ currentL = count;
}
+
+ return offset;
}
- int ISO7816BERTLV::decodeValue(unsigned char *buffer)
+ int ISO7816BERTLV::decodeValue(const unsigned char *buffer)
{
if (currentL == 0)
return 0;
- currentV.setBuffer(buffer, currentL);
+ currentV.assign(buffer, currentL);
return currentL;
}
- unsigned int ISO7816BERTLV::getClass()
+ unsigned int ISO7816BERTLV::getClass() const
{
return tagClass;
}
- unsigned int ISO7816BERTLV::getEncoding()
+ unsigned int ISO7816BERTLV::getEncoding() const
{
return encoding;
}
- ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, ByteArray buffer)
+ const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, const ByteArray &buffer)
{
unsigned char temp_tag[3] = { 0, };
unsigned char temp_tag_len = 0;
total_len += temp_tag_len;
/* add length's length */
- if (buffer.getLength() < 128)
+ if (buffer.size() < 128)
{
- temp_len[0] = buffer.getLength();
+ temp_len[0] = buffer.size();
temp_len_len = 1;
}
temp_len[0] = 0x80;
temp_len_len = 1;
- if (buffer.getLength() > 0x00FFFFFF)
+ if (buffer.size() > 0x00FFFFFF)
{
- temp_len[4] = (buffer.getLength() & 0xFF000000) >> 24;
+ temp_len[4] = (buffer.size() & 0xFF000000) >> 24;
temp_len_len++;
}
- if (buffer.getLength() > 0x0000FFFF)
+ if (buffer.size() > 0x0000FFFF)
{
- temp_len[3] = (buffer.getLength() & 0x00FF0000) >> 16;
+ temp_len[3] = (buffer.size() & 0x00FF0000) >> 16;
temp_len_len++;
}
- if (buffer.getLength() > 0x000000FF)
+ if (buffer.size() > 0x000000FF)
{
- temp_len[2] = (buffer.getLength() & 0x0000FF00) >> 8;
+ temp_len[2] = (buffer.size() & 0x0000FF00) >> 8;
temp_len_len++;
}
- temp_len[1] = buffer.getLength() & 0x000000FF;
+ temp_len[1] = buffer.size() & 0x000000FF;
temp_len_len++;
temp_len[0] |= temp_len_len;
}
/* add buffer's length */
- total_len += buffer.getLength();
+ total_len += buffer.size();
/* alloc new buffer */
temp_buffer = new unsigned char[total_len];
current += temp_len_len;
/* fill value */
- if (buffer.getLength() > 0)
- memcpy(temp_buffer + current, buffer.getBuffer(), buffer.getLength());
+ if (buffer.size() > 0)
+ memcpy(temp_buffer + current, buffer.getBuffer(), buffer.size());
- result.setBuffer(temp_buffer, total_len);
+ result.assign(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)
+ const 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)
+ TLVHelper *ISO7816BERTLV::getChildTLV(const ByteArray &data)
{
if (childTLV != NULL)
{
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* standard library header */
-#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 [%ld], param2 [%ld], error [%ld], 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 */
{
NumberStream::NumberStream(const ByteArray &T)
{
- setBuffer(T.getBuffer(), T.getLength());
+ assign(T.getBuffer(), T.size());
}
- unsigned int NumberStream::getBigEndianNumber()
+ unsigned int NumberStream::getBigEndianNumber() const
{
return getBigEndianNumber(*this);
}
- unsigned int NumberStream::getLittleEndianNumber()
+ unsigned int NumberStream::getLittleEndianNumber() const
{
return getLittleEndianNumber(*this);
}
{
if (this != &T)
{
- setBuffer(T.getBuffer(), T.getLength());
+ assign(T.getBuffer(), T.size());
}
return *this;
{
if (this != &T)
{
- setBuffer(T.getBuffer(), T.getLength());
+ assign(T.getBuffer(), T.size());
}
return *this;
int i, len;
unsigned int result = 0;
- len = (T.getLength() < 4) ? T.getLength() : 4;
+ len = (T.size() < 4) ? T.size() : 4;
for (i = 0; i < len; i++)
{
- result = (result << 8) | T.getAt(i);
+ result = (result << 8) | T.at(i);
}
return result;
int i, len;
unsigned int result = 0;
- len = (T.getLength() < 4) ? T.getLength() : 4;
+ len = (T.size() < 4) ? T.size() : 4;
for (i = 0; i < len; i++)
{
- result = result | (T.getAt(i) << (i * 8));
+ result = result | (T.at(i) << (i * 8));
}
return result;
BUF_MEM *bptr;
BIO *b64, *bmem;
- if (buffer.getLength() == 0)
+ if (buffer.size() == 0)
{
return ret;
}
b64 = BIO_push(b64, bmem);
- BIO_write(b64, buffer.getBuffer(), buffer.getLength());
+ BIO_write(b64, buffer.getBuffer(), buffer.size());
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
- result.setBuffer((unsigned char *)bptr->data, bptr->length);
+ result.assign((unsigned char *)bptr->data, bptr->length);
BIO_free_all(b64);
{
ByteArray temp;
- temp.setBuffer((unsigned char *)buffer, strlen(buffer));
+ temp.assign((unsigned char *)buffer, strlen(buffer));
return decodeBase64String(temp, result, newLineChar);
}
unsigned int length = 0;
char *temp;
- if (buffer.getBuffer() == NULL || buffer.getLength() == 0)
+ if (buffer.getBuffer() == NULL || buffer.size() == 0)
{
return ret;
}
- length = buffer.getLength();
+ length = buffer.size();
temp = new char[length];
if (temp != NULL)
memset(temp, 0, length);
b64 = BIO_new(BIO_f_base64());
- bmem = BIO_new_mem_buf(buffer.getBuffer(), length);
+ bmem = BIO_new_mem_buf((void *)buffer.getBuffer(), length);
if (newLineChar == false)
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_push(b64, bmem);
BIO_free_all(bmem);
- result.setBuffer((unsigned char *)temp, length);
+ result.assign((unsigned char *)temp, length);
delete []temp;
}
else
{
- SCARD_DEBUG_ERR("alloc failed");
+ _ERR("alloc failed");
}
return ret;
}
- bool OpensslHelper::digestBuffer(const char *algorithm, const uint8_t *buffer, const uint32_t length, ByteArray &result)
+ bool OpensslHelper::digestBuffer(const char *algorithm,
+ const uint8_t *buffer, uint32_t length, ByteArray &result)
{
- ByteArray temp((uint8_t *)buffer, (uint32_t)length);
+ ByteArray temp(buffer, length);
return digestBuffer(algorithm, temp, result);
}
- bool OpensslHelper::digestBuffer(const char *algorithm, const ByteArray &buffer, ByteArray &result)
+ bool OpensslHelper::digestBuffer(const char *algorithm,
+ const ByteArray &buffer, ByteArray &result)
{
const EVP_MD *md;
bool ret = false;
- if (algorithm == NULL || buffer.getLength() == 0)
+ if (algorithm == NULL || buffer.size() == 0)
{
return ret;
}
if (EVP_DigestInit(&mdCtx, md) > 0)
{
- if (EVP_DigestUpdate(&mdCtx, buffer.getBuffer(), buffer.getLength()) == 0)
+ if (EVP_DigestUpdate(&mdCtx, buffer.getBuffer(), buffer.size()) == 0)
{
- SCARD_DEBUG_ERR("EVP_DigestUpdate failed");
+ _ERR("EVP_DigestUpdate failed");
}
if (EVP_DigestFinal(&mdCtx, temp, &resultLen) > 0 &&
resultLen > 0)
{
- result.setBuffer(temp, resultLen);
+ result.assign(temp, resultLen);
ret = true;
}
}
}
else
{
- SCARD_DEBUG_ERR("EVP_get_digestbyname(\"%s\") returns NULL", algorithm);
+ _ERR("EVP_get_digestbyname(\"%s\") returns NULL", algorithm);
}
return ret;
{
static unsigned char aid[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50,
0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
- ByteArray PKCS15::PKCS15_AID(ARRAY_AND_SIZE(aid));
+ const ByteArray PKCS15::PKCS15_AID(ARRAY_AND_SIZE(aid));
- PKCS15::PKCS15(Channel *channel)
- : PKCS15Object(channel), odf(NULL)
+ PKCS15::PKCS15(Channel *channel) :
+ PKCS15Object(channel), odf(NULL)
+ {
+ }
+
+ PKCS15::PKCS15(Channel *channel, const ByteArray &selectResponse) :
+ PKCS15Object(channel, selectResponse), odf(NULL)
+ {
+ }
+
+ PKCS15::~PKCS15()
+ {
+ if (odf != NULL)
+ {
+ delete odf;
+ odf = NULL;
+ }
+ }
+
+ int PKCS15::select()
{
int ret;
- ret = select(PKCS15::PKCS15_AID);
- if (ret == FileObject::SUCCESS)
+ ret = PKCS15Object::select(PKCS15_AID);
+ if (ret >= SCARD_ERROR_OK)
{
- SCARD_DEBUG("response : %s", selectResponse.toString());
+ _DBG("response : %s", selectResponse.toString().c_str());
}
else if (ret == ResponseHelper::ERROR_FILE_NOT_FOUND)
{
- SCARD_DEBUG_ERR("PKCS15 AID not found, search in EF DIR");
+ _ERR("PKCS15 AID not found, search in EF DIR");
- if (selectFromEFDIR() == true)
+ ret = selectFromEFDIR();
+ if (ret >= SCARD_ERROR_OK)
{
- SCARD_DEBUG("response : %s", selectResponse.toString());
+ _DBG("response : %s", selectResponse.toString().c_str());
}
else
{
- SCARD_DEBUG_ERR("PKCS15 select failed, [%d]", ret);
+ _ERR("PKCS15 select failed, [%d]", ret);
}
}
else
{
- SCARD_DEBUG_ERR("PKCS15 select failed, [%d]", ret);
+ _ERR("PKCS15 select failed, [%d]", ret);
}
- }
- PKCS15::PKCS15(Channel *channel, ByteArray selectResponse)
- : PKCS15Object(channel, selectResponse), odf(NULL)
- {
- }
-
- PKCS15::~PKCS15()
- {
- if (odf != NULL)
- {
- delete odf;
- odf = NULL;
- }
+ return ret;
}
- bool PKCS15::selectFromEFDIR()
+ int PKCS15::selectFromEFDIR()
{
- bool result = false;
+ int ret;
ByteArray path;
EFDIR dir(channel);
- path = dir.getPathByAID(PKCS15_AID);
- if (path.getLength() > 0)
+ ret = dir.select();
+ if (ret >= SCARD_ERROR_OK)
{
- int ret;
-
- ret = select(path, false);
- if (ret == FileObject::SUCCESS)
+ path = dir.getPathByAID(PKCS15_AID);
+ if (path.size() > 0)
{
- result = true;
+ ret = PKCS15Object::select(path, false);
+ if (ret < SCARD_ERROR_OK)
+ {
+ _ERR("PKCS15 select failed, [%d]", ret);
+ }
}
else
{
- SCARD_DEBUG_ERR("path select failed, [%d]", ret);
+ _ERR("PKCS15 path is not found");
+ ret = SCARD_ERROR_NOT_SUPPORTED;
}
}
else
{
- SCARD_DEBUG_ERR("PKCS15 not found");
+ _ERR("select EFDIR failed, [%x]", -ret);
}
- return result;
+ return ret;
}
PKCS15ODF *PKCS15::getODF()
if (odf != NULL && odf->isClosed() == true)
{
- SCARD_DEBUG_ERR("failed to open ODF");
+ _ERR("failed to open ODF");
delete odf;
odf = NULL;
}
}
- SCARD_DEBUG("odf [%p]", odf);
+ _DBG("odf [%p]", odf);
return odf;
}
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "NumberStream.h"
+#include "PKCS15CDF.h"
+#include "SimpleTLV.h"
+
+namespace smartcard_service_api
+{
+ PKCS15CDF::PKCS15CDF(unsigned int fid, Channel *channel) :
+ PKCS15Object(channel)
+ {
+ int ret = 0;
+
+ if ((ret = select(fid)) >= SCARD_ERROR_OK)
+ {
+ ByteArray cdfData, extra;
+
+ _DBG("response : %s", selectResponse.toString().c_str());
+
+ ret = readBinaryAll(0, cdfData);
+ if (ret == SCARD_ERROR_OK)
+ {
+ _DBG("cdfData : %s", cdfData.toString().c_str());
+
+ parseData(cdfData);
+ }
+ else
+ {
+ _ERR("readBinary failed, [%d]", ret);
+ }
+ }
+ else
+ {
+ _ERR("select failed, [%d]", ret);
+ }
+ }
+
+ PKCS15CDF::PKCS15CDF(const ByteArray &path, Channel *channel) :
+ PKCS15Object(channel)
+ {
+ int ret = 0;
+
+ if ((ret = select(path)) >= SCARD_ERROR_OK)
+ {
+ ByteArray cdfData, extra;
+
+ _DBG("response : %s", selectResponse.toString().c_str());
+
+ ret = readBinaryAll(0, cdfData);
+ if (ret == SCARD_ERROR_OK)
+ {
+ _DBG("cdfData : %s", cdfData.toString().c_str());
+
+ parseData(cdfData);
+ }
+ else
+ {
+ _ERR("readBinary failed, [%d]", ret);
+ }
+ }
+ else
+ {
+ _ERR("select failed, [%d]", ret);
+ }
+ }
+
+ PKCS15CDF::~PKCS15CDF()
+ {
+ }
+
+ bool PKCS15CDF::parseData(const ByteArray &data)
+ {
+ int result;
+ SimpleTLV tlv(data);
+
+ while (tlv.decodeTLV())
+ {
+ CertificateType *cert;
+
+ _DBG("0x%02X [%d] : %s", tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
+
+ cert = new CertificateType();
+
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV())
+ {
+ _DBG("Common Object Attributes");
+
+ /* Common Object Attributes */
+ tlv.enterToValueTLV();
+ while (tlv.decodeTLV())
+ {
+ switch (tlv.getTag())
+ {
+ case (unsigned int)0x0C : /* label : OCTET STRING */
+ _DBG("label : %s", (char *)tlv.getValue().getBuffer());
+ cert->label.assign((char *)tlv.getValue().getBuffer(), tlv.getValue().getLength());
+ break;
+
+ case (unsigned int)0x03 : /* flags : BIT STRING */
+ /* 0 : private, 1 : modifiable */
+ _DBG("flag : %s", tlv.getValue()[0] ? "modifiable" : "private");
+ cert->modifiable = (tlv.getValue()[0] == 1);
+ break;
+
+ default :
+ _DBG("0x%02X [%d] : %s", tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
+ break;
+ }
+ }
+ tlv.returnToParentTLV();
+ }
+
+ if (tlv.decodeTLV())
+ {
+ _DBG("Common Certificate Attributes");
+
+ /* Common Certificate Attributes */
+ tlv.enterToValueTLV();
+ while (tlv.decodeTLV())
+ {
+ switch (tlv.getTag())
+ {
+ case (unsigned int)0x04 : /* iD : OCTET STRING */
+ _DBG("id : %s", tlv.getValue().toString().c_str());
+ cert->id = tlv.getValue();
+ break;
+
+ case (unsigned int)0x01 : /* Authority : BOOLEAN */
+ _DBG("authority : %s", tlv.getValue().toString().c_str());
+ cert->authority = tlv.getValue()[0];
+ break;
+
+ case (unsigned int)0xA1 : /* ??? : ??? */
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV()) {
+ _DBG(" 0x%02X [%d] : %s", tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV()) {
+ _DBG(" 0x%02X [%d] : %s", tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV()) {
+ _DBG(" 0x%02X [%d] : %s", tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV()) {
+ _DBG(" 0x%02X [%d] : %s", tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
+ }
+ tlv.returnToParentTLV();
+ }
+ if (tlv.decodeTLV()) {
+ _DBG(" 0x%02X [%d] : %s", tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
+ }
+ tlv.returnToParentTLV();
+ }
+ tlv.returnToParentTLV();
+ }
+ tlv.returnToParentTLV();
+ break;
+
+ default :
+ _DBG("0x%02X [%d] : %s", tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
+ break;
+ }
+ }
+ tlv.returnToParentTLV();
+ }
+
+ if (tlv.decodeTLV())
+ {
+ _DBG("Certificate Attributes");
+
+ /* Path or Object */
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV())
+ {
+ tlv.enterToValueTLV();
+ if (tlv.decodeTLV())
+ {
+ /* PATH */
+ tlv.enterToValueTLV();
+ while (tlv.decodeTLV())
+ {
+ switch (tlv.getTag())
+ {
+ case (unsigned int)0x04 : /* path : OCTET STRING */
+ cert->path = tlv.getValue();
+ _DBG("path : %s", cert->path.toString().c_str());
+ break;
+
+ case (unsigned int)0x02 : /* index : INTEGER */
+ cert->index = NumberStream::getBigEndianNumber(tlv.getValue());
+ _DBG("index : %d", cert->index);
+ break;
+
+ case (unsigned int)0x80 : /* length : INTEGER */
+ cert->length = NumberStream::getBigEndianNumber(tlv.getValue());
+ _DBG("length : %d", cert->length);
+ break;
+ }
+ }
+ tlv.returnToParentTLV();
+
+ FileObject file(channel);
+
+ result = file.select(cert->path, true);
+ if (result >= SCARD_ERROR_OK) {
+ result = file.readBinary(0, cert->length, cert->certificate);
+ if (result >= SCARD_ERROR_OK) {
+ _DBG("certificate[%d] : %s", cert->certificate.size(), cert->certificate.toString().c_str());
+ } else {
+ _ERR("readBinary failed, [%x]", result);
+ }
+ } else {
+ _ERR("select failed, [%x]", result);
+ }
+
+ }
+ tlv.returnToParentTLV();
+ }
+ tlv.returnToParentTLV();
+ }
+ tlv.returnToParentTLV();
+
+ listCertType.push_back(cert);
+ }
+
+ _INFO("listCertType.size() = %d", listCertType.size());
+
+ return (listCertType.size() > 0);
+ }
+
+ const CertificateType *PKCS15CDF::getCertificateType(int index) const
+ {
+ if (index < 0 || index >= (int)listCertType.size())
+ return NULL;
+
+ return listCertType[index];
+ }
+} /* namespace smartcard_service_api */
namespace smartcard_service_api
{
-// PKCS15DODF::PKCS15DODF():PKCS15Object()
-// {
-//
-// }
-
- PKCS15DODF::PKCS15DODF(unsigned int fid, Channel *channel):PKCS15Object(channel)
+ PKCS15DODF::PKCS15DODF(unsigned int fid, Channel *channel) :
+ PKCS15Object(channel)
{
int ret = 0;
- if ((ret = select(fid)) == 0)
+ if ((ret = select(fid)) >= SCARD_ERROR_OK)
{
ByteArray dodfData, extra;
- SCARD_DEBUG("response : %s", selectResponse.toString());
+ _DBG("response : %s", selectResponse.toString().c_str());
- if ((ret = readBinary(0, 0, getFCP()->getFileSize(), dodfData)) == 0)
+ if ((ret = readBinaryAll(0, dodfData)) == 0)
{
- SCARD_DEBUG("odfData : %s", dodfData.toString());
+ _DBG("dodfData : %s", dodfData.toString().c_str());
parseData(dodfData);
}
else
{
- SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+ _ERR("readBinary failed, [%d]", ret);
}
}
else
{
- SCARD_DEBUG_ERR("select failed, [%d]", ret);
+ _ERR("select failed, [%d]", ret);
}
}
- PKCS15DODF::PKCS15DODF(ByteArray path, Channel *channel):PKCS15Object(channel)
+ PKCS15DODF::PKCS15DODF(const ByteArray &path, Channel *channel) :
+ PKCS15Object(channel)
{
int ret = 0;
- if ((ret = select(path)) == 0)
+ if ((ret = select(path)) >= SCARD_ERROR_OK)
{
ByteArray dodfData, extra;
- SCARD_DEBUG("response : %s", selectResponse.toString());
+ _DBG("response : %s", selectResponse.toString().c_str());
- if ((ret = readBinary(0, 0, getFCP()->getFileSize(), dodfData)) == 0)
+ if ((ret = readBinaryAll(0, dodfData)) == 0)
{
- SCARD_DEBUG("dodfData : %s", dodfData.toString());
+ _DBG("dodfData : %s", dodfData.toString().c_str());
parseData(dodfData);
}
else
{
- SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+ _ERR("readBinary failed, [%d]", ret);
}
}
else
{
- SCARD_DEBUG_ERR("select failed, [%d]", ret);
+ _ERR("select failed, [%d]", ret);
}
}
{
}
- bool PKCS15DODF::parseData(ByteArray data)
+ bool PKCS15DODF::parseData(const ByteArray &data)
{
bool result = false;
SimpleTLV tlv(data);
{
PKCS15OID oid(tlv.getValue());
- SCARD_DEBUG("OID DataObject");
+ _DBG("OID DataObject : %s", oid.getOID().toString().c_str());
- pair<ByteArray, PKCS15OID> newPair(oid.getOID(), oid);
- mapOID.insert(newPair);
+ mapOID.insert(make_pair(oid.getOID(), oid));
}
break;
default :
- SCARD_DEBUG("Unknown tlv : t [%X], l [%d], v %s", tlv.getTag(), tlv.getLength(), tlv.getValue().toString());
+ _DBG("Unknown tlv : t [%X], l [%d], v %s", tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
break;
}
}
- SCARD_DEBUG("dataList.size() = %d", mapOID.size());
+ _INFO("dataList.size() = %d", mapOID.size());
return result;
}
- int PKCS15DODF::searchOID(ByteArray oid, ByteArray &data)
+ int PKCS15DODF::searchOID(const ByteArray &oid, ByteArray &data) const
{
int result = -1;
- map<ByteArray, PKCS15OID>::iterator item;
+ map<ByteArray, PKCS15OID>::const_iterator item;
item = mapOID.find(oid);
if (item != mapOID.end())
namespace smartcard_service_api
{
- PKCS15ODF::PKCS15ODF(Channel *channel)
- : PKCS15Object(channel), dodf(NULL)
+ static const unsigned int ODF_FID = 0x3150;
+
+ static const unsigned int TAG_DODF = (unsigned int)0xA7;
+ static const unsigned int TAG_CDF = (unsigned int)0xA5;
+
+ PKCS15ODF::PKCS15ODF(Channel *channel) :
+ PKCS15Object(channel), cdf(NULL), dodf(NULL)
{
int ret = 0;
- if ((ret = select(PKCS15ODF::ODF_FID)) == 0)
+ if ((ret = select(ODF_FID)) >= SCARD_ERROR_OK)
{
ByteArray odfData, extra;
- SCARD_DEBUG("response : %s", selectResponse.toString());
+ _DBG("response : %s", selectResponse.toString().c_str());
- if ((ret = readBinary(0, 0, getFCP()->getFileSize(), odfData)) == 0)
+ if ((ret = readBinaryAll(0, odfData)) == 0)
{
- SCARD_DEBUG("odfData : %s", odfData.toString());
+ _DBG("odfData : %s", odfData.toString().c_str());
parseData(odfData);
}
else
{
- SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+ _ERR("readBinary failed, [%d]", ret);
}
}
else
{
- SCARD_DEBUG_ERR("select failed, [%d]", ret);
+ _ERR("select failed, [%d]", ret);
}
}
- PKCS15ODF::PKCS15ODF(Channel *channel, ByteArray selectResponse)
- : PKCS15Object(channel, selectResponse), dodf(NULL)
+ PKCS15ODF::PKCS15ODF(Channel *channel, const ByteArray &selectResponse) :
+ PKCS15Object(channel, selectResponse), dodf(NULL)
{
int ret = 0;
ByteArray odfData;
- if ((ret = readBinary(0, 0, 0, odfData)) == 0)
+ if ((ret = readBinaryAll(0, odfData)) == 0)
{
- SCARD_DEBUG("odfData : %s", odfData.toString());
+ _DBG("odfData : %s", odfData.toString().c_str());
parseData(odfData);
}
else
{
- SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+ _ERR("readBinary failed, [%d]", ret);
}
}
}
}
- bool PKCS15ODF::parseData(ByteArray data)
+ bool PKCS15ODF::parseData(const ByteArray &data)
{
bool result = false;
SimpleTLV tlv(data);
{
switch (tlv.getTag())
{
- case (unsigned int)0xA7 ://PKCS15ODF::TAG_DODF :
+ case TAG_DODF :
{
ByteArray dodf;
- SCARD_DEBUG("TAG_DODF");
+ _DBG("TAG_DODF");
dodf = PKCS15Object::getOctetStream(tlv.getValue());
- SCARD_DEBUG("path : %s", dodf.toString());
+ _DBG("path : %s", dodf.toString().c_str());
pair<unsigned int, ByteArray> newPair(tlv.getTag(), dodf);
dataList.insert(newPair);
}
break;
- case (unsigned int)0xA5 ://PKCS15ODF::TAG_TOKENINFO :
+ case TAG_CDF :
{
ByteArray tokeninfo;
- SCARD_DEBUG("TAG_TOKENINFO");
+ _DBG("TAG_CDF");
tokeninfo = PKCS15Object::getOctetStream(tlv.getValue());
- SCARD_DEBUG("path : %s", tokeninfo.toString());
+ _DBG("path : %s", tokeninfo.toString().c_str());
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());
+ _DBG("Unknown tlv : t [%X], l [%d], v %s",
+ tlv.getTag(), tlv.size(), tlv.getValue().toString().c_str());
break;
}
}
- SCARD_DEBUG("dataList.size() = %d", dataList.size());
+ _INFO("dataList.size() = %d", dataList.size());
return result;
}
if (dodf == NULL)
{
- item = dataList.find((unsigned int)0xA7/*PKCS15ODF::TAG_DODF*/);
+ item = dataList.find(TAG_DODF);
if (item != dataList.end())
{
NumberStream num(item->second);
unsigned int fid = num.getLittleEndianNumber();
- SCARD_DEBUG("fid [%X]", fid);
+ _DBG("dodf fid [%X]", fid);
dodf = new PKCS15DODF(fid, channel);
if (dodf != NULL && dodf->isClosed() == true)
{
- SCARD_DEBUG_ERR("failed to open DODF");
+ _ERR("failed to open DODF");
delete dodf;
dodf = NULL;
}
else
{
- SCARD_DEBUG_ERR("[%02X] is not found. total [%d]", TAG_DODF, dataList.size());
+ _ERR("[%02X] is not found. total [%d]", TAG_DODF, dataList.size());
}
}
- SCARD_DEBUG("dodf [%p]", dodf);
+ _DBG("dodf [%p]", dodf);
return dodf;
}
+ PKCS15CDF *PKCS15ODF::getCDF()
+ {
+ map<unsigned int, ByteArray>::iterator item;
+
+ if (cdf == NULL)
+ {
+ item = dataList.find(TAG_CDF);
+ if (item != dataList.end())
+ {
+ NumberStream num(item->second);
+ unsigned int fid = num.getLittleEndianNumber();
+
+ _DBG("cdf fid [%X]", fid);
+
+ cdf = new PKCS15CDF(fid, channel);
+ if (cdf != NULL && cdf->isClosed() == true)
+ {
+ _ERR("failed to open CDF");
+
+ delete cdf;
+ cdf = NULL;
+ }
+ }
+ else
+ {
+ _ERR("[%02X] is not found. total [%d]", TAG_CDF, dataList.size());
+ }
+ }
+
+ _DBG("cdf [%p]", cdf);
+
+ return cdf;
+ }
} /* namespace smartcard_service_api */
namespace smartcard_service_api
{
- PKCS15OID::PKCS15OID(ByteArray data)
+ PKCS15OID::PKCS15OID(const ByteArray &data)
{
parseOID(data);
}
{
}
- bool PKCS15OID::parseOID(ByteArray data)
+ bool PKCS15OID::parseOID(const ByteArray &data)
{
bool result = false;
SimpleTLV tlv(data);
- SCARD_BEGIN();
+ _BEGIN();
while (tlv.decodeTLV() == true)
{
switch (tlv.getTag())
{
case PKCS15::TAG_SEQUENCE :
- if (tlv.getLength() > 0)
+ if (tlv.size() > 0)
{
/* common object attribute */
tlv.enterToValueTLV();
if (tlv.decodeTLV() == true && tlv.getTag() == 0x0C) /* ?? */
{
name = tlv.getValue();
- SCARD_DEBUG("name : %s", name.toString());
+ SECURE_LOGD("name : %s", name.toString().c_str());
}
tlv.returnToParentTLV();
}
{
/* common object attribute */
/* if you want to use this value, add member variable and parse here */
-// SCARD_DEBUG_ERR("common object attribute is empty");
+// _ERR("common object attribute is empty");
}
break;
case 0xA0 : /* CHOICE 0 : External Oid??? */
- SCARD_DEBUG_ERR("oid doesn't exist");
+ _ERR("oid doesn't exist");
break;
case 0xA1 : /* CHOICE 1 : OidDO */
{
oid = tlv.getValue();
- SCARD_DEBUG("oid : %s", oid.toString());
+ _DBG("oid : %s", oid.toString().c_str());
}
else
{
- SCARD_DEBUG_ERR("oid is empty");
+ _ERR("oid is empty");
}
/* path */
{
path = SimpleTLV::getOctetString(tlv.getValue());
- SCARD_DEBUG("path : %s", path.toString());
+ _DBG("path : %s", path.toString().c_str());
result = true;
}
else
{
- SCARD_DEBUG_ERR("sequence is empty");
+ _ERR("sequence is empty");
}
tlv.returnToParentTLV();
}
else
{
- SCARD_DEBUG_ERR("common dataobject attribute is empty");
+ _ERR("common dataobject attribute is empty");
}
tlv.returnToParentTLV();
break;
default :
- SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+ _ERR("Unknown tag : 0x%02X", tlv.getTag());
break;
}
}
- SCARD_END();
+ _END();
return result;
}
-
- ByteArray PKCS15OID::getOID()
- {
- return oid;
- }
-
- ByteArray PKCS15OID::getName()
- {
- return name;
- }
-
- ByteArray PKCS15OID::getPath()
- {
- return path;
- }
-
} /* namespace smartcard_service_api */
// {
// }
- PKCS15Object::PKCS15Object(Channel *channel):FileObject(channel)
+ PKCS15Object::PKCS15Object(Channel *channel) : FileObject(channel)
{
}
- PKCS15Object::PKCS15Object(Channel *channel, ByteArray selectResponse):FileObject(channel, selectResponse)
+ PKCS15Object::PKCS15Object(Channel *channel,
+ const ByteArray &selectResponse) :
+ FileObject(channel, selectResponse)
{
}
{
}
- ByteArray PKCS15Object::getOctetStream(const ByteArray &data)
+ const ByteArray PKCS15Object::getOctetStream(const ByteArray &data)
{
ByteArray result;
SimpleTLV tlv(data);
}
else
{
- SCARD_DEBUG_ERR("TAG_OCTET_STREAM not found");
+ _ERR("TAG_OCTET_STREAM not found");
}
tlv.returnToParentTLV();
}
else
{
- SCARD_DEBUG_ERR("TAG_SEQUENCE not found");
+ _ERR("TAG_SEQUENCE not found");
}
return result;
namespace smartcard_service_api
{
- PKCS15Path::PKCS15Path()
+ PKCS15Path::PKCS15Path() : index(-1), length(0)
+ {
+ }
+
+ PKCS15Path::PKCS15Path(const ByteArray &data) : index(-1), length(0)
+ {
+ parseData(data);
+ }
+
+ PKCS15Path::PKCS15Path(const ByteArray &path, int index) :
+ path(path), index(index), length(0)
+ {
+ }
+
+ PKCS15Path::PKCS15Path(const unsigned char *path,
+ size_t length, int index) :
+ path(path, length), index(index), length(0)
{
}
{
}
-// PKCS15Path(ByteArray &data);
-// PKCS15Path(ByteArray path, int index);
-// PKCS15Path(unsigned char *path, unsigned int length, int index);
-// ~PKCS15Path();
-//
-// bool PKCS15Path::parseData(ByteArray &data)
-// {
+ bool PKCS15Path::parseData(const ByteArray &data)
+ {
+ /* TODO */
// SimpleTLV tlv(data);
//
// if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE */
// path = tlv.getOctetString();
//
// if (tlv.decodeTLV())
-// index = t
-//
// }
-// }
-//
-// int getPath(ByteArray &path);
-// bool hasIndexLength();
-// int getIndex();
-// unsigned int getLength();
-// int encode(ByteArray &result);
+ return true;
+ }
+
+ int PKCS15Path::encode(ByteArray &result) const
+ {
+ /* TODO */
+ return 0;
+ }
} /* namespace smartcard_service_api */
namespace smartcard_service_api
{
- PKCS15TokenInfo::PKCS15TokenInfo(Channel *channel):PKCS15Object(channel)
+ PKCS15TokenInfo::PKCS15TokenInfo(Channel *channel) :
+ PKCS15Object(channel)
{
}
+++ /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() : seService(NULL), present(false)
- {
- memset(name, 0, sizeof(name));
- }
-} /* namespace smartcard_service_api */
*/
/* standard library header */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
#include <unistd.h>
#include <list>
#include <string>
#include <vector>
/* SLP library header */
-#include "package-manager.h"
#include "pkgmgr-info.h"
#include "aul.h"
namespace smartcard_service_api
{
- ByteArray SignatureHelper::getCertificationHash(const char *packageName)
+ int SignatureHelper::getPackageName(int pid, char *package, size_t length)
+ {
+ return aul_app_get_pkgname_bypid(pid, package, length);
+ }
+
+ const ByteArray SignatureHelper::getCertificationHash(const char *packageName)
{
ByteArray result;
int ret = 0;
- pkgmgr_certinfo_h handle = NULL;
+ pkgmgrinfo_certinfo_h handle = NULL;
pkgmgrinfo_appinfo_h handle_appinfo;
char *pkgid = NULL;
if(pkgmgrinfo_appinfo_get_appinfo(packageName, &handle_appinfo) != PMINFO_R_OK)
{
- SCARD_DEBUG_ERR("pkgmgrinfo_appinfo_get_appinfo fail");
+ _ERR("pkgmgrinfo_appinfo_get_appinfo fail");
return result;
}
if(pkgmgrinfo_appinfo_get_pkgid(handle_appinfo, &pkgid) != PMINFO_R_OK)
{
pkgmgrinfo_appinfo_destroy_appinfo(handle_appinfo);
- SCARD_DEBUG_ERR("pkgmgrinfo_appinfo_get_pkgid fail");
+ _ERR("pkgmgrinfo_appinfo_get_pkgid fail");
return result;
}
pkgmgrinfo_appinfo_destroy_appinfo(handle_appinfo);
- SCARD_DEBUG("package name : %s", pkgid);
+ SECURE_LOGD("package name : %s, package id : %s", packageName, pkgid);
- if ((ret = pkgmgr_pkginfo_create_certinfo(&handle)) == 0)
+ if ((ret = pkgmgrinfo_pkginfo_create_certinfo(&handle)) == 0)
{
- if ((ret = pkgmgr_pkginfo_load_certinfo(pkgid, handle)) == 0)
+ if ((ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, handle)) == 0)
{
int type;
- for (type = (int)PM_AUTHOR_ROOT_CERT; type <= (int)PM_DISTRIBUTOR2_SIGNER_CERT; type++)
+ for (type = (int)PMINFO_AUTHOR_ROOT_CERT; type <= (int)PMINFO_DISTRIBUTOR2_SIGNER_CERT; type++)
{
const char *value = NULL;
- if ((ret = pkgmgr_pkginfo_get_cert_value(handle, (pkgmgr_cert_type)type, &value)) == 0)
+ if ((ret = pkgmgrinfo_pkginfo_get_cert_value(handle, (pkgmgrinfo_cert_type)type, &value)) == 0)
{
if (value != NULL && strlen(value) > 0)
{
OpensslHelper::decodeBase64String(value, result, false);
- if (result.getLength() > 0)
+ if (result.size() > 0)
{
- SCARD_DEBUG("type [%d] hash [%d] : %s", type, result.getLength(), result.toString());
+ _DBG("type [%d] hash [%d] : %s", type, result.size(), result.toString().c_str());
break;
}
}
}
else
{
- SCARD_DEBUG_ERR("pkgmgr_pkginfo_load_certinfo failed [%d]", ret);
+ _ERR("pkgmgr_pkginfo_load_certinfo failed [%d]", ret);
}
- pkgmgr_pkginfo_destroy_certinfo(handle);
+ pkgmgrinfo_pkginfo_destroy_certinfo(handle);
}
else
{
- SCARD_DEBUG_ERR("pkgmgr_pkginfo_create_certinfo failed [%d]", ret);
+ _ERR("pkgmgr_pkginfo_create_certinfo failed [%d]", ret);
}
return result;
}
- ByteArray SignatureHelper::getCertificationHash(int pid)
+ const ByteArray SignatureHelper::getCertificationHash(int pid)
{
ByteArray result;
int error = 0;
}
else
{
- SCARD_DEBUG_ERR("aul_app_get_pkgname_bypid failed [%d]", error);
+ _ERR("aul_app_get_pkgname_bypid failed [%d]", error);
}
return result;
}
else
{
- SCARD_DEBUG_ERR("aul_app_get_pkgname_bypid failed [%d]", error);
+ _ERR("aul_app_get_pkgname_bypid failed [%d]", error);
}
return result;
{
bool result = false;
int ret = 0;
- pkgmgr_certinfo_h handle = NULL;
+ pkgmgrinfo_certinfo_h handle = NULL;
pkgmgrinfo_appinfo_h handle_appinfo;
char *pkgid = NULL;
- if(pkgmgrinfo_appinfo_get_appinfo(packageName, &handle_appinfo) != PMINFO_R_OK)
+ if (pkgmgrinfo_appinfo_get_appinfo(packageName, &handle_appinfo) != PMINFO_R_OK)
{
- SCARD_DEBUG_ERR("pkgmgrinfo_appinfo_get_appinfo fail");
+ _ERR("pkgmgrinfo_appinfo_get_appinfo fail");
return result;
}
- if(pkgmgrinfo_appinfo_get_pkgid(handle_appinfo, &pkgid) != PMINFO_R_OK)
+ if (pkgmgrinfo_appinfo_get_pkgid(handle_appinfo, &pkgid) != PMINFO_R_OK)
{
pkgmgrinfo_appinfo_destroy_appinfo(handle_appinfo);
- SCARD_DEBUG_ERR("pkgmgrinfo_appinfo_get_pkgid fail");
+ _ERR("pkgmgrinfo_appinfo_get_pkgid fail");
return result;
}
- SCARD_DEBUG("package name : %s", pkgid);
+ SECURE_LOGD("package name : %s, package id : %s", packageName, pkgid);
- if ((ret = pkgmgr_pkginfo_create_certinfo(&handle)) == 0)
+ if ((ret = pkgmgrinfo_pkginfo_create_certinfo(&handle)) == 0)
{
- if ((ret = pkgmgr_pkginfo_load_certinfo(pkgid, handle)) == 0)
+ if ((ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, handle)) == 0)
{
int type;
- for (type = (int)PM_AUTHOR_ROOT_CERT; type <= (int)PM_DISTRIBUTOR2_SIGNER_CERT; type++)
+ for (type = (int)PMINFO_AUTHOR_ROOT_CERT; type <= (int)PMINFO_DISTRIBUTOR2_SIGNER_CERT; type++)
{
const char *value = NULL;
- if ((ret = pkgmgr_pkginfo_get_cert_value(handle, (pkgmgr_cert_type)type, &value)) == 0)
+ if ((ret = pkgmgrinfo_pkginfo_get_cert_value(handle, (pkgmgrinfo_cert_type)type, &value)) == 0)
{
if (value != NULL && strlen(value) > 0)
{
ByteArray decodeValue, hash;
OpensslHelper::decodeBase64String(value, decodeValue, false);
- if (decodeValue.getLength() > 0)
+ if (decodeValue.size() > 0)
{
- OpensslHelper::digestBuffer("sha1", decodeValue.getBuffer(), decodeValue.getLength(), hash);
- if(hash.getLength() > 0)
+ OpensslHelper::digestBuffer("sha1", decodeValue.getBuffer(), decodeValue.size(), hash);
+ if(hash.size() > 0)
{
- SCARD_DEBUG("type [%d] hash [%d] : %s", type, hash.getLength(), hash.toString());
+ _DBG("type [%d] hash [%d] : %s", type, hash.size(), hash.toString().c_str());
certHashes.push_back(hash);
}
}
}
else
{
- SCARD_DEBUG_ERR("pkgmgr_pkginfo_load_certinfo failed [%d]", ret);
+ _ERR("pkgmgr_pkginfo_load_certinfo failed [%d]", ret);
}
pkgmgrinfo_appinfo_destroy_appinfo(handle_appinfo);
- pkgmgr_pkginfo_destroy_certinfo(handle);
+ pkgmgrinfo_pkginfo_destroy_certinfo(handle);
}
else
{
- SCARD_DEBUG_ERR("pkgmgr_pkginfo_create_certinfo failed [%d]", ret);
+ _ERR("pkgmgr_pkginfo_create_certinfo failed [%d]", ret);
}
return result;
if ((tmp = (certiHash *)calloc(1, sizeof(certiHash))) == NULL)
goto ERROR;
- tmp->length = (*item).getLength();
+ tmp->length = (*item).size();
if ((tmp->value = (uint8_t *)calloc(tmp->length, sizeof(uint8_t))) == NULL)
{
return head;
ERROR :
- SCARD_DEBUG_ERR("mem alloc fail");
+ _ERR("alloc fail");
while (head)
{
namespace smartcard_service_api
{
- SimpleTLV::SimpleTLV():TLVHelper()
+ SimpleTLV::SimpleTLV() : TLVHelper()
{
}
- SimpleTLV::SimpleTLV(TLVHelper *parent):TLVHelper(parent)
+ SimpleTLV::SimpleTLV(TLVHelper *parent) : TLVHelper(parent)
{
- parentTLV = parent;
}
- SimpleTLV::SimpleTLV(const ByteArray &array):TLVHelper(array)
+ SimpleTLV::SimpleTLV(const ByteArray &array) : TLVHelper(array)
{
}
- SimpleTLV::SimpleTLV(const ByteArray &array, TLVHelper *parent):TLVHelper(array, parent)
+ SimpleTLV::SimpleTLV(const ByteArray &array, TLVHelper *parent) :
+ TLVHelper(array, parent)
{
- parentTLV = parent;
}
SimpleTLV::~SimpleTLV()
}
}
- int SimpleTLV::decodeTag(unsigned char *buffer)
+ int SimpleTLV::decodeTag(const unsigned char *buffer)
{
/* 0x00 or 0xFF is invalid tag value */
if (buffer[0] == 0x00 || buffer[0] == 0xFF)
return 1;
}
- int SimpleTLV::decodeLength(unsigned char *buffer)
+ int SimpleTLV::decodeLength(const unsigned char *buffer)
{
int count = 0;
return count;
}
- int SimpleTLV::decodeValue(unsigned char *buffer)
+ int SimpleTLV::decodeValue(const unsigned char *buffer)
{
if (currentL == 0)
return 0;
- currentV.setBuffer(buffer, currentL);
+ currentV.assign(buffer, currentL);
return currentL;
}
- ByteArray SimpleTLV::encode(unsigned int tag, ByteArray buffer)
+ const ByteArray SimpleTLV::encode(unsigned int tag, const ByteArray &buffer)
{
bool isLongBuffer = false;
ByteArray result;
total_len += 1;
/* add length's length */
- if (buffer.getLength() < 255)
+ if (buffer.size() < 255)
{
total_len += 1;
}
- else if (buffer.getLength() < 65536)
+ else if (buffer.size() < 65536)
{
total_len += 3;
isLongBuffer = true;
}
/* add buffer's length */
- total_len += buffer.getLength();
+ total_len += buffer.size();
/* alloc new buffer */
temp_buffer = new unsigned char[total_len];
if (isLongBuffer == true)
{
temp_buffer[current++] = (unsigned char)(0xFF);
- temp_buffer[current++] = (unsigned char)(buffer.getLength() >> 8);
- temp_buffer[current++] = (unsigned char)(buffer.getLength());
+ temp_buffer[current++] = (unsigned char)(buffer.size() >> 8);
+ temp_buffer[current++] = (unsigned char)(buffer.size());
}
else
{
- temp_buffer[current++] = (unsigned char)(buffer.getLength());
+ temp_buffer[current++] = (unsigned char)(buffer.size());
}
/* fill value */
- if (buffer.getLength() > 0)
- memcpy(temp_buffer + current, buffer.getBuffer(), buffer.getLength());
+ if (buffer.size() > 0)
+ memcpy(temp_buffer + current, buffer.getBuffer(), buffer.size());
- result.setBuffer(temp_buffer, total_len);
+ result.assign(temp_buffer, total_len);
delete []temp_buffer;
return result;
}
- ByteArray SimpleTLV::encode(unsigned int tag, unsigned char *buffer, unsigned int length)
+ const ByteArray SimpleTLV::encode(unsigned int tag, unsigned char *buffer, unsigned int length)
{
return encode(tag, ByteArray(buffer, length));
}
- TLVHelper *SimpleTLV::getChildTLV(ByteArray data)
+ TLVHelper *SimpleTLV::getChildTLV(const ByteArray &data)
{
if (childTLV != NULL)
{
return (TLVHelper *)childTLV;
}
- ByteArray SimpleTLV::getOctetString(const ByteArray &array)
+ const ByteArray SimpleTLV::getOctetString(const ByteArray &array)
{
SimpleTLV tlv(array);
return SimpleTLV::getOctetString(tlv);
}
- ByteArray SimpleTLV::getOctetString(SimpleTLV &tlv)
+ const ByteArray SimpleTLV::getOctetString(SimpleTLV &tlv)
{
ByteArray result;
}
else
{
- SCARD_DEBUG_ERR("getOctetString failed (0x%02X)", tlv.getTag());
+ _ERR("getOctetString failed (0x%02X)", tlv.getTag());
}
return result;
if (tlv.decodeTLV() == true && tlv.getTag() == 0x80) /* BOOLEAN */
{
- if (tlv.getValue().getAt(0) == 0)
+ if (tlv.getValue().at(0) == 0)
result = false;
else
result = true;
}
else
{
- SCARD_DEBUG_ERR("getBoolean failed (0x%02X)", tlv.getTag());
+ _ERR("getBoolean failed (0x%02X)", tlv.getTag());
}
return result;
}
else
{
- SCARD_DEBUG_ERR("getInteger failed (0x%02X)", tlv.getTag());
+ _ERR("getInteger failed (0x%02X)", tlv.getTag());
}
return result;
*/
/* standard library header */
-#include <stdio.h>
-#include <string.h>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
/* SLP library header */
namespace smartcard_service_api
{
- void TLVHelper::initialize(TLVHelper *parent)
+ TLVHelper::TLVHelper() : currentTLV(this), parentTLV(NULL),
+ childTLV(NULL), offset(0), currentT(0), currentL(0)
{
- parentTLV = parent;
- childTLV = NULL;
- currentTLV = this;
- offset = 0;
- currentT = 0;
- currentL = 0;
}
- TLVHelper::TLVHelper()
+ TLVHelper::TLVHelper(TLVHelper *parent) : currentTLV(this),
+ parentTLV(parent), childTLV(NULL),
+ offset(0), currentT(0), currentL(0)
{
- initialize();
}
- TLVHelper::TLVHelper(TLVHelper *parent)
- {
- initialize(parent);
- }
-
- TLVHelper::TLVHelper(const ByteArray &array)
+ TLVHelper::TLVHelper(const ByteArray &array) : currentTLV(this),
+ parentTLV(NULL), childTLV(NULL),
+ offset(0), currentT(0), currentL(0)
{
setTLVBuffer(array);
}
- TLVHelper::TLVHelper(const ByteArray &array, TLVHelper *parent)
+ TLVHelper::TLVHelper(const ByteArray &array, TLVHelper *parent) :
+ currentTLV(this), parentTLV(NULL), childTLV(NULL),
+ offset(0), currentT(0), currentL(0)
{
setTLVBuffer(array, parent);
}
bool TLVHelper::setTLVBuffer(const ByteArray &array, TLVHelper *parent)
{
- initialize(parent);
-
- if (array.getLength() == 0)
+ if (array.size() == 0)
return false;
+ currentTLV = this;
+ parentTLV = parent;
+ childTLV = NULL;
+ offset = 0;
+ currentT = 0;
+ currentL = 0;
+
tlvBuffer = array;
return true;
}
- bool TLVHelper::setTLVBuffer(unsigned char *buffer, unsigned int length, TLVHelper *parent)
+ bool TLVHelper::setTLVBuffer(const unsigned char *buffer, unsigned int length, TLVHelper *parent)
{
return setTLVBuffer(ByteArray(buffer, length), parent);
}
currentT = 0;
currentL = 0;
- currentV.releaseBuffer();
+ currentV.clear();
if (isEndOfBuffer())
return false;
if (currentL > 0)
{
- if (currentL > (tlvBuffer.getLength() - (offset + temp)))
+ if (currentL > (tlvBuffer.size() - (offset + temp)))
return false;
/* V */
return true;
}
- const char *TLVHelper::toString()
+ const string TLVHelper::toString() const
{
- memset(strBuffer, 0, sizeof(strBuffer));
+ stringstream ss;
- if (currentL == 0)
- {
- snprintf(strBuffer, sizeof(strBuffer), "T [%X], L [%d]", getTag(), getLength());
- }
- else
+ ss << "T [" << getTag() << "], L [" << size() << "]";
+ if (currentL > 0)
{
- snprintf(strBuffer, sizeof(strBuffer), "T [%X], L [%d], V %s", getTag(), getLength(), getValue().toString());
+ ss << ", V " << getValue().toString();
}
- return strBuffer;
+ return ss.str();
}
TLVHelper *TLVHelper::getParentTLV()
bool result = false;
TLVHelper *temp = NULL;
- if (getLength() >= 2)
+ if (size() >= 2)
{
temp = currentTLV->getChildTLV(getValue());
{
bool result = true;
-// SCARD_DEBUG("current [%p], parent [%p]", currentTLV, currentTLV->getParentTLV());
-
if (currentTLV->getParentTLV() != NULL)
{
currentTLV = currentTLV->getParentTLV();
int status;
ByteArray dataField;
- static int parseStatusWord(unsigned char *sw);
+ static int parseStatusWord(const unsigned char *sw);
public:
static const int SUCCESS = 0;
~ResponseHelper();
bool setResponse(const ByteArray &response);
- int getStatus();
- unsigned char getSW1();
- unsigned char getSW2();
+ inline int getStatus() const { return status; }
+ inline unsigned char getSW1() const { return sw[0]; }
+ inline unsigned char getSW2() const { return sw[1]; }
// char *getErrorString();
- ByteArray getDataField();
+ inline const ByteArray getDataField() const { return dataField; }
static int getStatus(const ByteArray &response);
- static ByteArray getDataField(const ByteArray &response);
+ static const ByteArray getDataField(const ByteArray &response);
// static char *getErrorString();
};
// static const unsigned char P1_ = (unsigned char)0x;
static const unsigned char P2_SELECT_GET_FCP = (unsigned char)0x04;
+ static const unsigned char P2_SELECT_GET_FCI = (unsigned char)0x00;
// static const unsigned char P2_ = (unsigned char)0x;
static const unsigned char CLA_CHANNEL_STANDARD = (unsigned char)0x00;
~APDUCommand();
bool setCommand(unsigned char cla, unsigned char ins, unsigned char p1,
- unsigned char p2, ByteArray commandData, unsigned int maxResponseSize);
+ unsigned char p2, const ByteArray &commandData, unsigned int maxResponseSize);
bool setCommand(const ByteArray &command);
bool setChannel(int type, int channelNum);
void setCLA(unsigned char cla);
- unsigned char getCLA();
+ unsigned char getCLA() const;
void setINS(unsigned char ins);
- unsigned char getINS();
+ unsigned char getINS() const;
void setP1(unsigned char p1);
- unsigned char getP1();
+ unsigned char getP1() const;
void setP2(unsigned char p2);
- unsigned char getP2();
+ unsigned char getP2() const;
void setCommandData(const ByteArray &data);
- ByteArray getCommandData();
+ const ByteArray getCommandData() const;
void setMaxResponseSize(unsigned int maxResponseSize);
- unsigned int getMaxResponseSize();
+ unsigned int getMaxResponseSize() const;
- bool getBuffer(ByteArray &array);
+ bool getBuffer(ByteArray &array) const;
};
class APDUHelper
static const int COMMAND_WRITE_BINARY = 10;
static const int COMMAND_WRITE_RECORD = 11;
- static ByteArray generateAPDU(int command, int channel, ByteArray data);
+ static const ByteArray generateAPDU(int command,
+ int channel, const ByteArray &data);
};
} /* namespace smartcard_service_api */
#define ACCESSCONDITION_H_
/* standard library header */
-#include <vector>
#include <map>
+#include <vector>
/* SLP library header */
namespace smartcard_service_api
{
- class APDUAccessRule
+ class AccessRule
{
private :
- bool permission;
- map<ByteArray, ByteArray> mapApduFilters;
+ bool apduRule;
+ bool nfcRule;
+ vector<pair<ByteArray, ByteArray> > listFilters;
- public :
- APDUAccessRule()
- {
- permission = true;
- }
+ void printAccessRules() const;
- void loadAPDUAccessRule(const ByteArray &data);
- bool isAuthorizedAccess(const ByteArray &command);
+ public :
+ AccessRule() : apduRule(true), nfcRule(true) {}
- void printAPDUAccessRules();
- };
+ inline void setAPDUAccessRule(bool rule) { apduRule = rule; }
+ inline void setNFCAccessRule(bool rule) { nfcRule = rule; }
- class NFCAccessRule
- {
- private :
- bool permission;
+ void addAPDUAccessRule(const ByteArray &apdu,
+ const ByteArray &mask);
- public :
- NFCAccessRule()
+ inline bool isAuthorizedAccess(void) const
{
- permission = true;
+ return (apduRule || (listFilters.size() > 0));
}
+ bool isAuthorizedAPDUAccess(const ByteArray &command) const;
+ bool isAuthorizedNFCAccess(void) const;
- void loadNFCAccessRule(const ByteArray &data);
- bool isAuthorizedAccess(void);
-
- void printNFCAccessRules();
+ friend class AccessCondition;
};
class AccessCondition
{
private :
- bool permission;
ByteArray aid;
- vector<ByteArray> hashes;
- APDUAccessRule apduRule;
- NFCAccessRule nfcRule;
+ map<ByteArray, AccessRule> mapRules;
+
+ void printAccessConditions() const;
public :
- AccessCondition() : permission(false)
- {
- }
+ AccessCondition() {}
+
+ inline void setAID(const ByteArray &aid) { this->aid = aid; }
+ inline const ByteArray getAID() const { return aid; }
+ void setAccessCondition(bool rule);
+ void addAccessRule(const ByteArray &hash);
+
+ void setAPDUAccessRule(const ByteArray &certHash, bool rule);
+ void addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &apdu, const ByteArray &mask);
+ void addAPDUAccessRule(const ByteArray &certHash,
+ const ByteArray &rule);
+
+ void setNFCAccessRule(const ByteArray &certHash, bool rule);
+
+ bool isAuthorizedAccess(const ByteArray &certHash) const;
+ bool isAuthorizedAPDUAccess(const ByteArray &certHash,
+ const ByteArray &command) const;
+ bool isAuthorizedNFCAccess(const ByteArray &certHash) const;
+
+ AccessRule *getAccessRule(const ByteArray &certHash);
+ const AccessRule *getAccessRule(const ByteArray &certHash) const;
- void loadAccessCondition(ByteArray &aid, ByteArray &data);
- bool isAuthorizedAccess(ByteArray &certHash);
- bool isAuthorizedAPDUAccess(ByteArray &command);
- bool isAuthorizedNFCAccess();
- void printAccessConditions();
+ friend class AccessControlList;
};
} /* namespace smartcard_service_api */
/* local header */
#include "ByteArray.h"
#include "Channel.h"
+#include "AccessCondition.h"
using namespace std;
namespace smartcard_service_api
{
- class AccessCondition;
-
class AccessControlList
{
protected:
map<ByteArray, AccessCondition> mapConditions;
bool allGranted;
- void printAccessControlList();
- bool isAuthorizedAccess(ByteArray aid, ByteArray certHash, bool update);
+ const AccessRule *findAccessRule(const ByteArray &aid,
+ const ByteArray &hash) const;
+ AccessCondition &getAccessCondition(const ByteArray &aid);
+
+ void printAccessControlList() const;
public:
- static ByteArray AID_ALL;
- static ByteArray AID_DEFAULT;
+ static ByteArray ALL_SE_APPS;
+ static ByteArray DEFAULT_SE_APP;
+ static ByteArray ALL_DEVICE_APPS;
AccessControlList();
virtual ~AccessControlList();
int updateACL(Channel *channel) { return loadACL(channel); }
void releaseACL();
- bool isAuthorizedAccess(ByteArray aid, ByteArray certHash);
- bool isAuthorizedAccess(unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength);
- bool isAuthorizedAccess(ByteArray aid, vector<ByteArray> &certHashes);
+ /* FIXME ??? */
+ inline bool hasConditions() const { return mapConditions.size() > 0; }
+
+ virtual bool isAuthorizedAccess(const ByteArray &aid,
+ const ByteArray &certHash) const;
+ virtual bool isAuthorizedAccess(const unsigned char *aidBuffer,
+ unsigned int aidLength, const unsigned char *certHashBuffer,
+ unsigned int certHashLength) const;
+ virtual bool isAuthorizedAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const;
+ virtual bool isAuthorizedAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes, const ByteArray &command) const;
+ virtual bool isAuthorizedNFCAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const;
};
} /* namespace smartcard_service_api */
#define BYTEARRAY_H_
/* standard library header */
+#include <string>
#include <stdint.h>
+#include <stddef.h>
/* SLP library header */
#define ARRAY_AND_SIZE(x) (uint8_t *)(&x), sizeof(x)
+using namespace std;
+
namespace smartcard_service_api
{
class ByteArray //: public Serializable
{
protected:
uint8_t *buffer;
- uint32_t length;
- char strBuffer[100];
+ size_t length;
- bool _setBuffer(uint8_t *array, uint32_t bufferLen);
+ bool _assign(uint8_t *array, size_t size);
void save(const char *filePath);
public:
static ByteArray EMPTY;
ByteArray();
- ByteArray(uint8_t *array, uint32_t bufferLen);
+ ByteArray(const uint8_t *array, size_t size);
ByteArray(const ByteArray &T);
~ByteArray();
// ByteArray serialize();
// void deserialize(ByteArray buffer);
- bool setBuffer(uint8_t *array, uint32_t bufferLen);
- void releaseBuffer();
+ bool assign(const uint8_t *array, size_t size);
+ inline bool setBuffer(const uint8_t *array, size_t size) { return assign(array, size); }
+ void clear();
+
+ size_t size() const;
+ inline size_t getLength() const { return size(); }
+ uint8_t *getBuffer();
+ const uint8_t *getBuffer() const;
+ uint8_t *getBuffer(size_t offset);
+ const uint8_t *getBuffer(size_t offset) const;
- uint32_t getLength() const;
- uint8_t *getBuffer() const;
- uint8_t *getBuffer(uint32_t offset) const;
+ uint8_t at(size_t index) const;
+ uint8_t reverseAt(size_t index) const;
- uint8_t getAt(uint32_t index) const;
- uint8_t getReverseAt(uint32_t index) const;
+ size_t extract(uint8_t *array, size_t size) const;
- uint32_t copyFromArray(uint8_t *array, uint32_t bufferLen) const;
+ const ByteArray sub(size_t offset, size_t size) const;
/* operator overloading */
ByteArray &operator =(const ByteArray &T);
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;
+ uint8_t operator [](size_t index) const;
- inline bool isEmpty() { return (buffer == (void *)0 || length == 0); }
- const char *toString();
+ inline bool isEmpty() const { return (buffer == (void *)0 || length == 0); }
+ const string toString(bool entire) const;
+ const string toString() const;
};
} /* 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);
+ typedef void (*transmitCallback)(unsigned char *buffer,
+ unsigned int length, int error, void *userParam);
+ typedef void (*closeChannelCallback)(int error, void *userParam);
class Channel : public Synchronous
{
protected :
ByteArray selectResponse;
+ ByteArray transmitResponse;
SessionHelper *session;
int channelNum;
- Channel() : Synchronous() { channelNum = -1; }
- Channel(SessionHelper *session) : Synchronous() { this->session = session; }
+ Channel() : session(NULL), channelNum(-1) {}
+ Channel(SessionHelper *session) : session(session), channelNum(-1) {}
- inline void setSelectResponse(ByteArray &response) { selectResponse = response; }
+ inline void setSelectResponse(const ByteArray &response) { selectResponse = response; }
public :
virtual ~Channel() {};
inline bool isBasicChannel() const throw() { return (channelNum == 0); }
inline bool isClosed() const throw() { return (channelNum < 0); }
- inline ByteArray getSelectResponse() const throw() { return selectResponse; }
+ inline const ByteArray getSelectResponse() const throw() { return selectResponse; }
+ inline const ByteArray getTransmitResponse() const throw() { return transmitResponse; }
inline SessionHelper *getSession() const throw() { return session; }
- virtual int close(closeCallback callback, void *userParam) = 0;
- virtual int transmit(ByteArray command, transmitCallback callback, void *userData) = 0;
+ virtual int close(closeChannelCallback callback, void *userParam) = 0;
+ virtual int transmit(const ByteArray &command, transmitCallback callback, void *userData) = 0;
virtual void closeSync()
throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &) = 0;
- virtual int transmitSync(ByteArray command, ByteArray &result)
+ virtual int transmitSync(const ByteArray &command, ByteArray &result)
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &) = 0;
};
#define DEBUG_H_
/* standard library header */
+#include <iostream>
/* 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(fmt, ##__VA_ARGS__);\
- } while (0)
-
-#define SCARD_DEBUG_ERR(fmt, ...)\
- do\
- {\
- LOGE(COLOR_RED fmt COLOR_END, ##__VA_ARGS__);\
- }while (0)
-
-#define SCARD_BEGIN() \
- do\
- {\
- LOGD(COLOR_BLUE"BEGIN >>>>"COLOR_END);\
- } while( 0 )
-
-#define SCARD_END() \
- do\
- {\
- LOGD(COLOR_BLUE"END <<<<"COLOR_END);\
- } \
- while( 0 )
+#define COLOR_BLACK "\033[0;30m"
+#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_GRAY "\033[0;37m"
+#define COLOR_END "\033[0;m"
+
+#define _ERR(fmt, ...) \
+ do \
+ { \
+ LOGE(COLOR_RED fmt COLOR_END, ##__VA_ARGS__); \
+ } \
+ while (0)
+
+#define _INFO(fmt, ...) \
+ do \
+ { \
+ LOGI(COLOR_GREEN fmt COLOR_END, ##__VA_ARGS__); \
+ } \
+ while (0)
+
+#define _WARN(fmt, ...) \
+ do \
+ { \
+ LOGI(COLOR_BROWN fmt COLOR_END, ##__VA_ARGS__); \
+ } \
+ while (0)
+
+#define _DBG(fmt, ...) \
+ do \
+ { \
+ LOGD(fmt, ##__VA_ARGS__); \
+ } \
+ while (0)
+
+#define _BEGIN() \
+ do \
+ { \
+ LOGD(COLOR_BLUE "BEGIN >>>>" COLOR_END); \
+ } \
+ while (0)
+
+#define _END() \
+ do \
+ { \
+ LOGD(COLOR_BLUE "END <<<<" COLOR_END); \
+ } \
+ while (0)
#endif /* DEBUG_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef 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(DispatcherMsg *msg):Message()
- {
- peerSocket = msg->peerSocket;
- 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_ */
class EFDIR : public FileObject
{
private:
- ByteArray parseRecord(Record &record, ByteArray &aid);
+ const ByteArray parseRecord(const Record &record, const ByteArray &aid);
public:
- static const unsigned int EFDIR_FID = 0x002f;
-
EFDIR(Channel *channel);
- EFDIR(Channel *channel, ByteArray selectResponse);
+ EFDIR(Channel *channel, const ByteArray &selectResponse);
~EFDIR();
- ByteArray getPathByAID(ByteArray &aid);
+ int select();
+
+ const ByteArray getPathByAID(const ByteArray &aid);
};
} /* namespace smartcard_service_api */
#endif /* EFDIR_H_ */
#include "smartcard-types.h"
+#define THROW_ERROR(errorCode) \
+ { \
+ switch (errorCode) \
+ { \
+ case SCARD_ERROR_OK : \
+ /* do nothing */ \
+ break; \
+ \
+ case SCARD_ERROR_IPC_FAILED : \
+ case SCARD_ERROR_IO_FAILED : \
+ case SCARD_ERROR_OPERATION_TIMEOUT : \
+ throw ErrorIO(errorCode); \
+ break; \
+ \
+ case SCARD_ERROR_SECURITY_NOT_ALLOWED : \
+ throw ErrorSecurity(errorCode); \
+ break; \
+ \
+ case SCARD_ERROR_UNAVAILABLE : \
+ case SCARD_ERROR_NOT_SUPPORTED : \
+ case SCARD_ERROR_NOT_INITIALIZED : \
+ case SCARD_ERROR_SE_NOT_INITIALIZED : \
+ case SCARD_ERROR_ILLEGAL_STATE : \
+ case SCARD_ERROR_OPERATION_NOT_SUPPORTED : \
+ throw ErrorIllegalState(errorCode); \
+ break; \
+ \
+ case SCARD_ERROR_ILLEGAL_PARAM : \
+ case SCARD_ERROR_ILLEGAL_REFERENCE : \
+ throw ErrorIllegalParameter(errorCode); \
+ break; \
+ \
+ default : \
+ case SCARD_ERROR_UNKNOWN : \
+ case SCARD_ERROR_OUT_OF_MEMORY : \
+ case SCARD_ERROR_NOT_ENOUGH_RESOURCE : \
+ case SCARD_ERROR_NEED_MORE_BUFFER : \
+ throw ExceptionBase(errorCode); \
+ break; \
+ } \
+ }
+
namespace smartcard_service_api
{
class ExceptionBase : public std::exception
#define FCI_H_
/* standard library header */
+#include <string>
/* SLP library header */
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;
+ int fileSize;
+ int totalFileSize;
+ int fid;
+ int sfi;
+ int maxRecordSize;
+ int numberOfRecord;
+ int fileType;
+ int fileStructure;
+ int lcs;
void resetMemberVar();
public:
FCP();
- FCP(ByteArray &array);
+ FCP(const ByteArray &array);
~FCP();
- bool setFCP(ByteArray array);
- ByteArray getFCP();
+ bool setFCP(const ByteArray &array);
+ const ByteArray getFCP() const;
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();
+ int getFileSize() const;
+ int getTotalFileSize() const;
+ int getFID() const;
+ int getSFI() const;
+ int getMaxRecordSize() const;
+ int getNumberOfRecord() const;
+ int getFileType() const;
+ int getFileStructure() const;
+ int getLCS() const;
+
+ const string toString() const;
};
class FCM
FCI();
~FCI();
- bool setFCIBuffer(ByteArray array);
+ bool setFCIBuffer(const ByteArray &array);
};
} /* namespace smartcard_service_api */
FCP fcp;
bool opened;
- int _select(ByteArray command);
+ int _select(const ByteArray &command);
protected:
ByteArray selectResponse;
- bool setSelectResponse(ByteArray &response);
+ bool setSelectResponse(const ByteArray &response);
public:
static const int SUCCESS = 0;
static const unsigned int MF_FID = 0x003F;
FileObject(Channel *channel);
- FileObject(Channel *channel, ByteArray selectResponse);
+ FileObject(Channel *channel, const ByteArray &selectResponse);
~FileObject();
void close();
- inline bool isClosed() { return (opened == false); }
- int select(ByteArray aid);
- int select(ByteArray path, bool fromCurrentDF);
+ inline bool isClosed() const { return (opened == false); }
+ int select(const ByteArray &aid);
+ int select(const ByteArray &path, bool fromCurrentDF);
int select(unsigned int fid);
int selectParent();
- FCI *getFCI();
- FCP *getFCP();
+ inline const ByteArray getSelectResponse() const { return selectResponse; }
+
+ const FCI *getFCI() const;
+ const FCP *getFCP() const;
int readRecord(unsigned int sfi, unsigned int recordId, Record &result);
- int writeRecord(unsigned int sfi, Record record);
+ int writeRecord(unsigned int sfi, const Record &record);
- int searchRecord(unsigned int sfi, ByteArray searchParam, vector<int> &result);
+ int searchRecord(unsigned int sfi, const ByteArray &searchParam, vector<int> &result);
int readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result);
- int writeBinary(unsigned int sfi, ByteArray data, unsigned int offset, unsigned int length);
+ int readBinary(unsigned int sfi, unsigned int length, ByteArray &result);
+ int writeBinary(unsigned int sfi, const ByteArray &data, unsigned int offset, unsigned int length);
+ int writeBinary(unsigned int sfi, const ByteArray &data);
+
+ int readBinaryAll(unsigned int sfi, ByteArray &result);
};
} /* namespace smartcard_service_api */
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GDBUSHELPER_H_
+#define GDBUSHELPER_H_
+
+#include <glib.h>
+
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class CallbackParam
+ {
+ public :
+ void *instance;
+ void *callback;
+ void *user_param;
+ };
+
+ class GDBusHelper
+ {
+ public :
+ static void convertVariantToByteArray(GVariant *var,
+ ByteArray &array);
+
+ static GVariant *convertByteArrayToVariant(
+ const ByteArray &array);
+ };
+} /* namespace smartcard_service_api */
+
+#endif /* GDBUSHELPER_H_ */
* limitations under the License.
*/
-#ifndef SERVERIPC_H_
-#define SERVERIPC_H_
+#ifndef GPACE_H_
+#define GPACE_H_
/* standard library header */
-#ifdef __cplusplus
-#include <map>
-#endif /* __cplusplus */
/* SLP library header */
/* local header */
+#include "smartcard-types.h"
#ifdef __cplusplus
-#include "IPCHelper.h"
+#include "AccessControlList.h"
#endif /* __cplusplus */
#ifdef __cplusplus
-using namespace std;
-
namespace smartcard_service_api
{
- class ServerIPC: public IPCHelper
+ class GPACE : public AccessControlList
{
- 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();
- Message *retrieveMessage(int socket);
-
- friend class ServerResource;
+ private :
+ AccessControlList *acl;
+
+ public :
+ GPACE();
+ ~GPACE();
+
+ int loadACL(Channel *channel);
+
+ bool isAuthorizedAccess(const ByteArray &aid,
+ const ByteArray &certHash) const;
+ bool isAuthorizedAccess(const unsigned char *aidBuffer,
+ unsigned int aidLength,
+ const unsigned char *certHashBuffer,
+ unsigned int certHashLength) const;
+ bool isAuthorizedAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const;
+ bool isAuthorizedAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes,
+ const ByteArray &command) const;
+ bool isAuthorizedNFCAccess(const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const;
};
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
-
-/* export C API */
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-void server_ipc_create_listen_socket();
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* SERVERIPC_H_ */
+#endif /* GPACE_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GPARAACL_H_
+#define GPARAACL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "AccessControlList.h"
+#include "GPARAM.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class GPARAACL : public AccessControlList
+ {
+ private:
+ ByteArray refreshTag;
+
+ void addCondition(const ByteArray &aid, const ByteArray &hash,
+ const vector<ByteArray> &apduRule, const ByteArray &nfcRule);
+
+ int updateRule(const ByteArray &data);
+
+ public:
+ GPARAACL();
+ ~GPARAACL();
+
+ int loadACL(Channel *channel);
+ int loadACL(GPARAM &aram);
+
+ bool isAuthorizedAccess(GPARAM &aram, const ByteArray &aid,
+ const ByteArray &certHash) const;
+ bool isAuthorizedAccess(GPARAM &aram, const ByteArray &aid,
+ const ByteArray &certHash,
+ const ByteArray &command) const;
+ bool isAuthorizedAccess(GPARAM &aram,
+ const unsigned char *aidBuffer,
+ unsigned int aidLength,
+ const unsigned char *certHashBuffer,
+ unsigned int certHashLength) const;
+ bool isAuthorizedAccess(GPARAM &aram, const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const;
+ bool isAuthorizedAccess(GPARAM &aram, const ByteArray &aid,
+ const vector<ByteArray> &certHashes,
+ const ByteArray &command) const;
+ bool isAuthorizedNFCAccess(GPARAM &aram, const ByteArray &aid,
+ const vector<ByteArray> &certHashes) const;
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+#endif /* GPARAACL_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GPARAM_H_
+#define GPARAM_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "FileObject.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ class GPARAM : public FileObject
+ {
+ public:
+ GPARAM(Channel *channel);
+ GPARAM(Channel *channel, const ByteArray &selectResponse);
+ ~GPARAM() {}
+
+ int select();
+
+ int getDataAll(ByteArray &data);
+ int getDataSpecific(const ByteArray &aid, const ByteArray &hash, ByteArray &data);
+ int getDataRefreshTag(ByteArray &tag);
+
+ /* override not supported functions */
+ int select(const ByteArray &aid) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int select(const ByteArray &path, bool fromCurrentDF) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int select(unsigned int fid) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int selectParent() { return SCARD_ERROR_NOT_SUPPORTED; }
+ int readRecord(unsigned int sfi, unsigned int recordId, Record &result) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int writeRecord(unsigned int sfi, const Record &record) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int searchRecord(unsigned int sfi, const ByteArray &searchParam, vector<int> &result) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result) { return SCARD_ERROR_NOT_SUPPORTED; }
+ int writeBinary(unsigned int sfi, const ByteArray &data, unsigned int offset, unsigned int length) { return SCARD_ERROR_NOT_SUPPORTED; }
+ };
+
+} /* namespace smartcard_service_api */
+#endif /* GPARAM_H_ */
* limitations under the License.
*/
-#ifndef CLIENTDISPATCHER_H_
-#define CLIENTDISPATCHER_H_
+#ifndef GPARFACL_H_
+#define GPARFACL_H_
/* standard library header */
-#include <map>
/* SLP library header */
/* local header */
-#include "DispatcherHelper.h"
-
-using namespace std;
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "AccessControlList.h"
+#include "PKCS15.h"
+#endif /* __cplusplus */
+#ifdef __cplusplus
namespace smartcard_service_api
{
- class SEService;
-
- class ClientDispatcher: public DispatcherHelper
+ class GPARFACL : public AccessControlList
{
private:
- map<void *, SEService *> mapSESerivces;
-
- ClientDispatcher();
- ~ClientDispatcher();
+ ByteArray refreshTag;
- void *dispatcherThreadFunc(DispatcherMsg *msg, void *data);
+ int loadAccessControl(Channel *channel, PKCS15DODF *dodf);
+ int loadRules(Channel *channel, const ByteArray &path);
+ int loadAccessConditions(Channel *channel, const ByteArray &aid, const ByteArray &path);
public:
- static ClientDispatcher &getInstance();
+ GPARFACL();
+ ~GPARFACL();
- bool addSEService(void *context, SEService *service);
- void removeSEService(void *context);
+ int loadACL(Channel *channel);
};
-} /* namespace open_mobile_api */
-#endif /* CLIENTDISPATCHER_H_ */
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+#endif /* GPARFACL_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef 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:
- ByteArray refreshTag;
-
- static ByteArray OID_GLOBALPLATFORM;
-
- int loadAccessControl(Channel *channel, PKCS15DODF *dodf);
- int loadRules(Channel *channel, ByteArray path);
- int loadAccessConditions(Channel *channel, ByteArray aid, ByteArray path);
-
- public:
- GPSEACL();
- ~GPSEACL();
-
- int loadACL(Channel *channel);
-
- };
-
-} /* namespace smartcard_service_api */
-#endif /* __cplusplus */
-
-/* export C API */
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-typedef void *gp_se_acl_h;
-
-gp_se_acl_h gp_se_acl_create_instance();
-int gp_se_acl_load_acl(gp_se_acl_h handle, channel_h channel);
-int gp_se_acl_update_acl(gp_se_acl_h handle, channel_h channel);
-void gp_se_acl_release_acl(gp_se_acl_h handle);
-bool gp_se_acl_is_authorized_access(gp_se_acl_h handle, unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength);
-void gp_se_acl_destroy_instance(gp_se_acl_h handle);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* GPSEACL_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef IPCHELPER_H_
-#define IPCHELPER_H_
-
-/* standard library header */
-#include <glib.h>
-#include <pthread.h>
-#ifdef USE_IPC_EPOLL
-#include <sys/epoll.h>
-#endif
-
-/* 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;
-#ifdef CLIENT_IPC_THREAD
-#ifdef USE_IPC_EPOLL
- static const int EPOLL_SIZE = 5;
- int fdPoll;
- struct epoll_event *pollEvents;
-#else
- fd_set fdSetRead;
-#endif
- pthread_t readThread;
-
- static void *threadRead(void *data);
- int eventPoll();
-#endif
-
- 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();
- virtual ~IPCHelper();
-
- bool createListenSocket();
- bool createConnectSocket();
- void destroyListenSocket();
- void destroyConnectSocket();
-
- bool sendMessage(int socket, Message *msg);
- bool sendMessage(int socket, ByteArray &buffer);
- Message *retrieveMessage();
- ByteArray retrieveBuffer(int socket);
- Message *retrieveMessage(int socket);
-
- void setDispatcher(DispatcherHelper *dispatcher);
-
-#ifdef CLIENT_IPC_THREAD
- friend void *threadRead(void *data);
-#endif
- friend gboolean channelCallbackFunc(GIOChannel* channel, GIOCondition condition, gpointer data);
- };
-
-} /* namespace smartcard_service_api */
-#endif /* IPCHELPER_H_ */
namespace smartcard_service_api
{
- class ISO7816BERTLV: public TLVHelper
+ 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);
+ int decodeTag(const unsigned char *buffer);
+ int decodeLength(const unsigned char *buffer);
+ int decodeValue(const unsigned char *buffer);
- TLVHelper *getChildTLV(ByteArray data);
+ TLVHelper *getChildTLV(const ByteArray &data);
public:
ISO7816BERTLV();
ISO7816BERTLV(const ByteArray &array);
~ISO7816BERTLV();
- unsigned int getClass();
- unsigned int getEncoding();
+ unsigned int getClass() const;
+ unsigned int getEncoding() const;
- 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);
+ static const ByteArray encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, const ByteArray &buffer);
+ static const ByteArray encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length);
};
} /* namespace smartcard_service_api */
#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))
+ if (AutoLockHelper TOKENPASTE2(lock_, __LINE__) = makeAutoLock(X))
class AutoLockHelper
{
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef 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 long param1;
- unsigned long param2;
- ByteArray data;
- long error;
- void *caller;
- void *callback;
- void *userParam;
-
- Message();
- ~Message();
-
- ByteArray serialize();
- void deserialize(unsigned char *buffer, unsigned int length);
- void deserialize(ByteArray buffer);
-
- inline bool isSynchronousCall() { return (caller == callback); }
-
- const char *toString();
- };
-
-} /* namespace smartcard_service_api */
-#endif /* MESSAGE_H_ */
namespace smartcard_service_api
{
- class NumberStream: public ByteArray
+ class NumberStream : public ByteArray
{
public:
NumberStream(const ByteArray &T);
- unsigned int getBigEndianNumber();
- unsigned int getLittleEndianNumber();
+ unsigned int getBigEndianNumber() const;
+ unsigned int getLittleEndianNumber() const;
static unsigned int getBigEndianNumber(const ByteArray &T);
static unsigned int getLittleEndianNumber(const ByteArray &T);
{
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);
+ 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);
+ static bool digestBuffer(const char *algorithm,
+ const uint8_t *buffer, uint32_t length,
+ ByteArray &result);
+ static bool digestBuffer(const char *algorithm,
+ const ByteArray &buffer, ByteArray &result);
};
} /* namespace smartcard_service_api */
map<unsigned int, ByteArray> recordElement;
PKCS15ODF *odf;
- bool selectFromEFDIR();
+ int selectFromEFDIR();
public:
- static ByteArray PKCS15_AID;
+ static const ByteArray PKCS15_AID;
PKCS15(Channel *channel);
- PKCS15(Channel *channel, ByteArray selectResponse);
+ PKCS15(Channel *channel, const ByteArray &selectResponse);
~PKCS15();
+ int select();
+
PKCS15ODF *getODF();
- int getTokenInfo(ByteArray &path);
+ int getTokenInfo(ByteArray &path) const;
};
} /* namespace smartcard_service_api */
* limitations under the License.
*/
-#ifndef DISPATCHERHELPER_H_
-#define DISPATCHERHELPER_H_
+#ifndef PKCS15CDF_H_
+#define PKCS15CDF_H_
/* standard library header */
-#include <queue>
-#include <pthread.h>
/* SLP library header */
/* local header */
-#include "Synchronous.h"
-#include "DispatcherMsg.h"
-
-using namespace std;
+#include "PKCS15Object.h"
+#include "PKCS15OID.h"
namespace smartcard_service_api
{
- class DispatcherHelper : public Synchronous
+ class CertificateType
{
- private:
- pthread_t dispatcherThread;
-
- queue<DispatcherMsg *> messageQ;
-
- static void *_dispatcherThreadFunc(void *data);
+ public :
+ /* Common Object Attributes */
+ string label;
+ bool modifiable;
+
+ /* Common Certificate Attributes */
+ ByteArray id;
+ int authority;
+
+ /* Certificate Attributes */
+ ByteArray path;
+ int index;
+ size_t length;
+ ByteArray certificate;
+ };
- DispatcherMsg *fetchMessage();
+ class PKCS15CDF : public PKCS15Object
+ {
+ private:
+ vector<CertificateType *> listCertType;
- protected:
- virtual void *dispatcherThreadFunc(DispatcherMsg *msg, void *data) = 0;
+ bool parseData(const ByteArray &data);
public:
- DispatcherHelper();
- ~DispatcherHelper();
-
- void clearQueue();
-
- void pushMessage(DispatcherMsg *msg);
- void processMessage(DispatcherMsg *msg);
-
- bool runDispatcherThread();
- void stopDispatcherThread();
+ PKCS15CDF(unsigned int fid, Channel *channel);
+ PKCS15CDF(const ByteArray &path, Channel *channel);
+ ~PKCS15CDF();
- friend void *_dispatcherThreadFunc(void *data);
+ inline size_t getCount() const { return listCertType.size(); }
+ const CertificateType *getCertificateType(int index) const;
};
} /* namespace smartcard_service_api */
-#endif /* DISPATCHERHELPER_H_ */
+#endif /* PKCS15DODF_H_ */
namespace smartcard_service_api
{
- class PKCS15DODF: public PKCS15Object
+ class PKCS15DODF : public PKCS15Object
{
private:
map<ByteArray, PKCS15OID> mapOID;
- bool parseData(ByteArray data);
+ bool parseData(const ByteArray &data);
public:
- PKCS15DODF();
PKCS15DODF(unsigned int fid, Channel *channel);
- PKCS15DODF(ByteArray path, Channel *channel);
+ PKCS15DODF(const ByteArray &path, Channel *channel);
~PKCS15DODF();
- int searchOID(ByteArray oid, ByteArray &data);
+ int searchOID(const ByteArray &oid, ByteArray &data) const;
};
} /* namespace smartcard_service_api */
/* local header */
#include "FileObject.h"
+#include "PKCS15CDF.h"
#include "PKCS15DODF.h"
using namespace std;
namespace smartcard_service_api
{
- class PKCS15ODF: public PKCS15Object
+ class PKCS15ODF : public PKCS15Object
{
private:
- bool parseData(ByteArray data);
+ PKCS15CDF *cdf;
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;
+ bool parseData(const ByteArray &data);
-// PKCS15ODF();
+ public:
PKCS15ODF(Channel *channel);
- PKCS15ODF(Channel *channel, ByteArray selectResponse);
+ PKCS15ODF(Channel *channel, const ByteArray &selectResponse);
~PKCS15ODF();
int getPuKDFPath(ByteArray &path);
int getPrKDFPath(ByteArray &path);
int getAODFPath(ByteArray &path);
- int getCDFFPath(ByteArray &path);
+ int getCDFPath(ByteArray &path);
int getDODFPath(ByteArray &path);
+ PKCS15CDF *getCDF();
PKCS15DODF *getDODF();
};
ByteArray name;
ByteArray path;
- bool parseOID(ByteArray data);
+ bool parseOID(const ByteArray &data);
public:
- PKCS15OID(ByteArray data);
+ PKCS15OID(const ByteArray &data);
~PKCS15OID();
- ByteArray getOID();
- ByteArray getName();
- ByteArray getPath();
-
+ inline const ByteArray getOID() const { return oid; }
+ inline const ByteArray getName() const { return name; }
+ inline const ByteArray getPath() const { return path; }
};
} /* namespace smartcard_service_api */
namespace smartcard_service_api
{
- class PKCS15Object: public FileObject
+ class PKCS15Object : public FileObject
{
protected:
map<unsigned int, ByteArray> dataList;
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(Channel *channel, const ByteArray &selectResponse);
~PKCS15Object();
- int decodePath(ByteArray path, PKCS15Path &result);
- int getPath(unsigned int type, PKCS15Path &result);
- int getPaths(vector<PKCS15Path> &paths);
+ int decodePath(const ByteArray &path, PKCS15Path &result);
+ int getPath(unsigned int type, PKCS15Path &result) const;
+ int getPaths(vector<PKCS15Path> &paths) const;
- static ByteArray getOctetStream(const ByteArray &data);
+ static const ByteArray getOctetStream(const ByteArray &data);
};
} /* namespace smartcard_service_api */
private :
ByteArray path;
int index;
- int length;
+ size_t length;
- bool parseData(ByteArray &data);
+ bool parseData(const ByteArray &data);
public:
PKCS15Path();
- PKCS15Path(ByteArray &data);
- PKCS15Path(ByteArray path, int index);
- PKCS15Path(unsigned char *path, unsigned int length, int index);
+ PKCS15Path(const ByteArray &data);
+ PKCS15Path(const ByteArray &path, int index);
+ PKCS15Path(const unsigned char *path,
+ size_t length, int index);
~PKCS15Path();
- int getPath(ByteArray &path);
- bool hasIndexLength();
- int getIndex();
- unsigned int getLength();
- int encode(ByteArray &result);
+ inline const ByteArray getPath() const { return path; }
+ inline bool hasIndexLength() const { return (length != 0); }
+ inline int getIndex() const { return index; }
+ inline size_t size() const { return length; }
+ int encode(ByteArray &result) const;
};
} /* namespace smartcard_service_api */
namespace smartcard_service_api
{
- class PKCS15TokenInfo: public PKCS15Object
+ class PKCS15TokenInfo : public PKCS15Object
{
public:
PKCS15TokenInfo(Channel *channel);
protected:
Channel *channel;
-// ProviderHelper();
-
public:
- ProviderHelper(Channel *channel);
- ~ProviderHelper();
+ ProviderHelper(Channel *channel) : channel(channel) {}
+ virtual ~ProviderHelper() {}
- Channel *getChannel();
+ inline Channel *getChannel() { return channel; }
};
} /* namespace smartcard_service_api */
/* standard library header */
#include <vector>
+#include <string>
/* SLP library header */
{
class SEServiceHelper;
- typedef void (*openSessionCallback)(SessionHelper *session, int error, void *userData);
+ typedef void (*openSessionCallback)(SessionHelper *session, int error,
+ void *userData);
class ReaderHelper : public Synchronous
{
protected:
- char name[30];
- vector<SessionHelper *> sessions;
SEServiceHelper *seService;
+ string name;
bool present;
+ vector<SessionHelper *> sessions;
- ReaderHelper();
+ ReaderHelper() : seService(NULL), present(false) {}
+ ReaderHelper(const char *name) : seService(NULL), name(name),
+ present(false) {}
virtual ~ReaderHelper() {}
public:
- inline const char *getName() { return name; }
- inline SEServiceHelper *getSEService() { return seService; }
- inline bool isSecureElementPresent() { return present; }
+ inline const char *getName() const { return name.c_str(); }
+ inline SEServiceHelper *getSEService() const { return seService; }
+ inline bool isSecureElementPresent() const { return present; }
virtual void closeSessions()
throw(ErrorIO &, ErrorIllegalState &) = 0;
public:
Record() : id(0) {}
- Record(unsigned int id, ByteArray buffer)
- : id(id), data(buffer) {};
+ Record(unsigned int id, const ByteArray &buffer) : id(id),
+ data(buffer) {};
~Record() {}
- inline unsigned int getID() { return id; }
- inline ByteArray getData() { return data; }
+ inline unsigned int getID() const { return id; }
+ inline const ByteArray getData() const { return data; }
};
} /* namespace smartcard_service_api */
public:
SEServiceHelper() : connected(false) {}
- virtual ~SEServiceHelper();
+ virtual ~SEServiceHelper() {}
vector<ReaderHelper *> getReaders() { return readers; }
bool isConnected() { return connected; }
{
class Serializable
{
- virtual ByteArray serialize() = 0;
- virtual void deserialize(ByteArray buffer) = 0;
+ virtual const ByteArray serialize() const = 0;
+ virtual void deserialize(const ByteArray &buffer) = 0;
};
} /* namespace smartcard_service_api */
bool closed;
public:
- SessionHelper(ReaderHelper *reader);
+ SessionHelper(ReaderHelper *reader) :
+ reader(reader), closed(true) {}
virtual ~SessionHelper() {}
ReaderHelper *getReader() const throw() { return reader; }
virtual int getATR(getATRCallback callback, void *userData) = 0;
virtual int close(closeSessionCallback callback, void *userData) = 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;
+ virtual int openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData) = 0;
+ virtual int openBasicChannel(const unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData) = 0;
+ virtual int openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData) = 0;
+ virtual int openLogicalChannel(const unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData) = 0;
- virtual ByteArray getATRSync()
+ virtual const ByteArray getATRSync()
throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &) = 0;
throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &) = 0;
- virtual Channel *openBasicChannelSync(ByteArray aid)
- throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &) = 0;
+ virtual Channel *openBasicChannelSync(const ByteArray &aid)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &) = 0;
- virtual Channel *openBasicChannelSync(unsigned char *aid, unsigned int length)
- throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &) = 0;
+ virtual Channel *openBasicChannelSync(const unsigned char *aid, unsigned int length)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &) = 0;
- virtual Channel *openLogicalChannelSync(ByteArray aid)
- throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &) = 0;
+ virtual Channel *openLogicalChannelSync(const ByteArray &aid)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &) = 0;
- virtual Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length)
- throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &) = 0;
+ virtual Channel *openLogicalChannelSync(const unsigned char *aid, unsigned int length)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &) = 0;
+
+ virtual Channel *openBasicChannelSync(const ByteArray &aid, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &) = 0;
+
+ virtual Channel *openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &) = 0;
+
+ virtual Channel *openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &) = 0;
+
+ virtual Channel *openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &) = 0;
};
} /* namespace smartcard_service_api */
class SignatureHelper
{
public:
- static ByteArray getCertificationHash(const char *packageName);
- static ByteArray getCertificationHash(int pid);
+ static int getPackageName(int pid, char *package, size_t length);
+ static const ByteArray getCertificationHash(const char *packageName);
+ static const ByteArray getCertificationHash(int pid);
static bool getCertificationHashes(int pid, vector<ByteArray> &certHashes);
static bool getCertificationHashes(const char *packageName, vector<ByteArray> &certHashes);
};
typedef struct _certiHash
{
- uint8_t *value;
- uint32_t length;
- struct _certiHash *next;
-}certiHash;
+ uint8_t *value;
+ uint32_t length;
+ struct _certiHash *next;
+} certiHash;
typedef void (*signature_helper_get_certificate_hashes_cb)(void *user_param, uint8_t *hash, uint32_t length);
SimpleTLV(TLVHelper *parent);
SimpleTLV(const ByteArray &array, TLVHelper *parent);
- int decodeTag(unsigned char *buffer);
- int decodeLength(unsigned char *buffer);
- int decodeValue(unsigned char *buffer);
+ int decodeTag(const unsigned char *buffer);
+ int decodeLength(const unsigned char *buffer);
+ int decodeValue(const unsigned char *buffer);
- TLVHelper *getChildTLV(ByteArray data);
+ TLVHelper *getChildTLV(const ByteArray &data);
public:
SimpleTLV();
SimpleTLV(const ByteArray &array);
~SimpleTLV();
- static ByteArray getOctetString(const ByteArray &array);
+ static const ByteArray getOctetString(const ByteArray &array);
static bool getBoolean(const ByteArray &array);
static int getInteger(const ByteArray &array);
- static ByteArray getOctetString(SimpleTLV &tlv);
+ static const 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);
+ static const ByteArray encode(unsigned int tag, const ByteArray &buffer);
+ static const ByteArray encode(unsigned int tag, unsigned char *buffer, unsigned int length);
};
} /* namespace smartcard_service_api */
TLVHelper *parentTLV;
TLVHelper *childTLV;
- char strBuffer[200];
ByteArray tlvBuffer;
unsigned int offset;
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 int decodeTag(const unsigned char *buffer) = 0;
+ virtual int decodeLength(const unsigned char *buffer) = 0;
+ virtual int decodeValue(const unsigned char *buffer) = 0;
- virtual TLVHelper *getChildTLV(ByteArray data) = 0;
+ virtual TLVHelper *getChildTLV(const ByteArray &data) = 0;
TLVHelper *getParentTLV();
bool setTLVBuffer(const ByteArray &array, TLVHelper *parent);
- bool setTLVBuffer(unsigned char *buffer, unsigned int length, TLVHelper *parent);
+ bool setTLVBuffer(const unsigned char *buffer, unsigned int length, TLVHelper *parent);
- bool _isEndOfBuffer() { return offset >= tlvBuffer.getLength(); }
+ inline bool _isEndOfBuffer() const { return offset >= tlvBuffer.size(); }
bool _decodeTLV();
- unsigned int _getTag() { return currentT; }
- unsigned int _getLength() { return currentL; }
- ByteArray _getValue() { return currentV; }
+ inline unsigned int _getTag() const { return currentT; }
+ inline unsigned int _size() const { return currentL; }
+ inline const ByteArray _getValue() const { return currentV; }
public:
TLVHelper();
TLVHelper(const ByteArray &array);
- ~TLVHelper();
+ virtual ~TLVHelper();
bool setTLVBuffer(const ByteArray &array) { return setTLVBuffer(array, NULL); }
- bool setTLVBuffer(unsigned char *buffer, unsigned int length) { return setTLVBuffer(buffer, length, NULL); }
+ bool setTLVBuffer(const unsigned char *buffer, unsigned int length) { return setTLVBuffer(buffer, length, NULL); }
- bool isEndOfBuffer() { return currentTLV->_isEndOfBuffer(); }
- bool decodeTLV() { return currentTLV->_decodeTLV(); }
+ inline bool isEndOfBuffer() const { return currentTLV->_isEndOfBuffer(); }
+ inline bool decodeTLV() { return currentTLV->_decodeTLV(); }
- unsigned int getTag() { return currentTLV->_getTag(); }
- unsigned int getLength() { return currentTLV->_getLength(); }
- ByteArray getValue() { return currentTLV->_getValue(); }
+ unsigned int getTag() const { return currentTLV->_getTag(); }
+ unsigned int size() const { return currentTLV->_size(); }
+ const ByteArray getValue() const { return currentTLV->_getValue(); }
- const char *toString();
+ const string toString() const;
bool enterToValueTLV();
bool returnToParentTLV();
namespace smartcard_service_api
{
- typedef void (*terminalNotificationCallback)(void *terminal, int event, int error, void *user_param);
+ typedef void (*terminalNotificationCallback)(const 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);
+ typedef void (*terminalTransmitCallback)(const unsigned char *buffer, unsigned int length, int error, void *userParam);
+ typedef void (*terminalGetATRCallback)(const unsigned char *buffer, unsigned int length, int error, void *userParam);
class Terminal : public Synchronous
{
protected:
terminalNotificationCallback statusCallback;
bool initialized;
+ bool closed;
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;
- }
+ Terminal() : statusCallback(NULL), initialized(false),
+ closed(true), name(NULL) {}
+
virtual ~Terminal() {}
virtual bool initialize() = 0;
virtual void finalize() = 0;
- inline bool isInitialized() { return initialized; }
+ inline bool isInitialized() const { return initialized; }
+
+ virtual bool open() = 0;
+ virtual void close() = 0;
+ inline bool isClosed() const { return closed; }
- inline char *getName() { return name; }
+ inline const char *getName() const { return name; }
inline void setStatusCallback(terminalNotificationCallback callback) { statusCallback = callback; }
- virtual bool isSecureElementPresence() = 0;
+ virtual bool isSecureElementPresence() const = 0;
- virtual int transmitSync(ByteArray command, ByteArray &result) = 0;
+ virtual int transmitSync(const ByteArray &command, ByteArray &result) = 0;
virtual int getATRSync(ByteArray &atr) = 0;
- virtual int transmit(ByteArray command, terminalTransmitCallback callback, void *userData) = 0;
+ virtual int transmit(const ByteArray &command, terminalTransmitCallback callback, void *userData) = 0;
virtual int getATR(terminalGetATRCallback callback, void *userData) = 0;
};
Name: smartcard-service-common
Description: Make flags of Common library of Smartcard service
Version: 1.0
-Requires: dlog
+Requires: glib-2.0 dlog
Libs: -L${libdir} -lsmartcard-service-common
-Cflags: -I${includedir}/smartcard-service-common
+Cflags: -I${includedir}/smartcard-service-common
\ No newline at end of file
--- /dev/null
+<!--
+ org.tizen.SmartcardService
+-->
+
+<node>
+ <interface name="org.tizen.SmartcardService.SeService">
+ <!--
+ SeService
+ -->
+ <method name="SeService">
+ <arg type="i" name="result" direction="out" />
+ <arg type="u" name="handle" direction="out" />
+ <arg type="a(us)" name="readers" direction="out" />
+ </method>
+
+ <!--
+ shutdown
+ -->
+ <method name="shutdown">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ </method>
+
+ <!--
+ ReaderInserted
+ -->
+ <signal name="ReaderInserted">
+ <arg type="u" name="reader_id" />
+ <arg type="s" name="reader_name" />
+ </signal>
+
+ <!--
+ ReaderRemoved
+ -->
+ <signal name="ReaderRemoved">
+ <arg type="u" name="reader_id" />
+ <arg type="s" name="reader_name" />
+ </signal>
+ </interface>
+
+ <interface name="org.tizen.SmartcardService.Reader">
+ <!--
+ openSession
+ -->
+ <method name="openSession">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="reader_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ <arg type="u" name="handle" direction="out" />
+ </method>
+ </interface>
+
+ <interface name="org.tizen.SmartcardService.Session">
+ <!--
+ getATR
+ -->
+ <method name="getATR">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="session_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ <arg type="a(y)" name="atr" direction="out" />
+ </method>
+ <!--
+ openChannel
+ -->
+ <method name="openChannel">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="session_id" direction="in" />
+ <arg type="u" name="type" direction="in" />
+ <arg type="a(y)" name="aid" direction="in" />
+ <arg type="y" name="P2" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ <arg type="u" name="handle" direction="out" />
+ <arg type="i" name="channel_number" direction="out" />
+ <arg type="a(y)" name="select_response" direction="out" />
+ </method>
+ <!--
+ closeSession
+ -->
+ <method name="closeSession">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="session_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ </method>
+ </interface>
+
+ <interface name="org.tizen.SmartcardService.Channel">
+ <!--
+ transmit
+ -->
+ <method name="transmit">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="channel_id" direction="in" />
+ <arg type="a(y)" name="command" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ <arg type="a(y)" name="response" direction="out" />
+ </method>
+ <!--
+ closeChannel
+ -->
+ <method name="closeChannel">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="channel_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ </method>
+ </interface>
+</node>
-Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
-
-
-
+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
-Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
-
-
-
+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
-Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
-
-
-
+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
+# FOR COMMENTING DEFINITION, MUST USE %% instead of %
+%global use_autostart "-DUSE_AUTOSTART=1"
+#%%global test_client "-DTEST_CLIENT=1"
+
+################################################################################
+# package : smartcard-service #
+################################################################################
Name: smartcard-service
Summary: Smartcard Service FW
-Version: 0.1.20
+Version: 0.1.41
Release: 0
Group: libs
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
-#IFNDEF USE_AUTOSTART
-#Source1: smartcard-service-server.init
-#ENDIF
+%if 0%{!?use_autostart:1}
+Source1: %{name}-server.init
+%endif
+BuildRequires: cmake
BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gio-unix-2.0)
BuildRequires: pkgconfig(security-server)
BuildRequires: pkgconfig(dlog)
-BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(aul)
BuildRequires: pkgconfig(libssl)
-BuildRequires: pkgconfig(dbus-glib-1)
BuildRequires: pkgconfig(pkgmgr)
BuildRequires: pkgconfig(pkgmgr-info)
-BuildRequires: cmake
-BuildRequires: gettext-tools
+BuildRequires: python
+BuildRequires: python-xml
+BuildRequires: hash-signer
Requires(post): /sbin/ldconfig
-Requires(post): /usr/bin/vconftool
-requires(postun): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+Requires: %{name}-common = %{version}-%{release}
+
%description
Smartcard Service FW.
-%prep
-%setup -q
+%files
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_libdir}/lib%{name}.so.*
+%{_datadir}/license/%{name}
+
+
+%post
+/sbin/ldconfig
+
+
+%postun
+/sbin/ldconfig
+
+
+################################################################################
+# package : smartcard-service-devel #
+################################################################################
%package devel
-Summary: smartcard service
+Summary: smartcard service devel
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
+
%description devel
smartcard service.
-%package -n smartcard-service-common
+
+%files devel
+%manifest %{name}-devel.manifest
+%defattr(-,root,root,-)
+%{_includedir}/%{name}/*
+%{_libdir}/lib%{name}.so
+%{_libdir}/pkgconfig/%{name}.pc
+
+
+################################################################################
+# package : smartcard-service-common #
+################################################################################
+%package common
Summary: common smartcard service
Group: Development/Libraries
-Requires: %{name} = %{version}-%{release}
-%description -n smartcard-service-common
+
+%description common
common smartcard service.
-%package -n smartcard-service-common-devel
+
+%files common
+%manifest %{name}-common.manifest
+%defattr(-,root,root,-)
+%{_libdir}/lib%{name}-common.so.*
+%{_datadir}/license/%{name}-common
+
+
+################################################################################
+# package : smartcard-service-common-devel #
+################################################################################
+%package common-devel
Summary: common smartcard service
Group: Development/Libraries
-Requires: %{name} = %{version}-%{release}
-Requires: smartcard-service-common = %{version}-%{release}
+Requires: %{name}-common = %{version}-%{release}
-%description -n smartcard-service-common-devel
+
+%description 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.
+%files common-devel
+%manifest %{name}-common-devel.manifest
+%defattr(-,root,root,-)
+%{_includedir}/%{name}-common/*
+%{_libdir}/lib%{name}-common.so
+%{_libdir}/pkgconfig/%{name}-common.pc
-%build
-#IFNDEF USE_AUTOSTART
-#cmake .. -DCMAKE_INSTALL_PREFIX=%{_prefix}
-#ELSE
-%cmake . -DUSE_AUTOSTART=1 # daemon will be started when client makes instance by DBUS
-#ENDIF
-#make %{?jobs:-j%jobs}
-%install
-rm -rf %{buildroot}
-#IFNDEF USE_AUTOSTART
-#%__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
-#ENDIF
-mkdir -p %{buildroot}/usr/share/license
-cp -af LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
-cp -af LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}-devel
-cp -af LICENSE.APLv2 %{buildroot}/usr/share/license/smartcard-service-server
-cp -af LICENSE.APLv2 %{buildroot}/usr/share/license/smartcard-service-common
-cp -af LICENSE.APLv2 %{buildroot}/usr/share/license/smartcard-service-common-devel
+################################################################################
+# package : smartcard-service-server #
+################################################################################
+%global bindir /usr/apps/%{name}-server
-%make_install
+%package server
+Summary: server smartcard service
+Group: Development/Libraries
+Requires: %{name}-common = %{version}-%{release}
-%post
-/sbin/ldconfig
-#IFNDEF USE_AUTOSTART
-#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
-#ENDIF
+%description server
+smartcard service server
-%postun
-/sbin/ldconfig
-#IFNDEF USE_AUTOSTART
-#rm -f /etc/rc.d/rc3.d/S79smartcard-service-server
-#rm -f /etc/rc.d/rc5.d/S79smartcard-service-server
-#ENDIF
-%files
-%manifest smartcard-service.manifest
-%defattr(-,root,root,-)
-%{_libdir}/libsmartcard-service.so.*
-/usr/share/license/%{name}
+%post server
+/usr/bin/signing-client/hash-signer-client.sh -a -d -p platform %{bindir}
+%if 0%{!?use_autostart:1}
+ ln -sf /etc/init.d/%{name}-server /etc/rc.d/rc3.d/S79%{name}-server
+ ln -sf /etc/init.d/%{name}-server /etc/rc.d/rc5.d/S79%{name}-server
+%endif
+ln -sf /usr/apps/%{name}-server/bin/smartcard-daemon /usr/bin/smartcard-daemon
+%if 0%{?test_client:1}
+ ln -sf /usr/apps/%{name}-server/bin/smartcard-test-client /usr/bin/smartcard-test-client
+%endif
-%files devel
-%manifest smartcard-service-devel.manifest
-%defattr(-,root,root,-)
-%{_includedir}/smartcard-service/*
-%{_libdir}/libsmartcard-service.so
-%{_libdir}/pkgconfig/smartcard-service.pc
-/usr/share/license/%{name}-devel
-%files -n smartcard-service-common
-%manifest smartcard-service-common.manifest
-%defattr(-,root,root,-)
-%{_libdir}/libsmartcard-service-common.so.*
-/usr/share/license/smartcard-service-common
+%postun server
+%if 0%{!?use_autostart:1}
+ rm -f /etc/rc.d/rc3.d/S79%{name}-server
+ rm -f /etc/rc.d/rc5.d/S79%{name}-server
+%endif
+rm -f /usr/bin/smartcard-daemon
-%files -n smartcard-service-common-devel
-%manifest smartcard-service-common-devel.manifest
-%defattr(-,root,root,-)
-%{_includedir}/smartcard-service-common/*
-%{_libdir}/libsmartcard-service-common.so
-%{_libdir}/pkgconfig/smartcard-service-common.pc
-/usr/share/license/smartcard-service-common-devel
-%files -n smartcard-service-server
-%manifest smartcard-service-server.manifest
+%files server
+%manifest %{name}-server.manifest
%defattr(-,root,root,-)
-%{_bindir}/smartcard-daemon
-#/usr/bin/smartcard-test-client
-#IFNDEF USE_AUTOSTART
-#/etc/init.d/smartcard-service-server
-#ELSE
-/usr/share/dbus-1/services/org.tizen.smartcard_service.service
-#ENDIF
-/usr/share/license/smartcard-service-server
+%{bindir}/bin/smartcard-daemon
+%{_datadir}/packages/%{name}-server.xml
+%if 0%{?test_client:1}
+ %{bindir}/bin/smartcard-test-client
+%endif
+%if 0%{?use_autostart:1}
+ %{_datadir}/dbus-1/services/org.tizen.smartcard_service.service
+%else
+ %{_sysconfdir}/init.d/%{name}-server
+%endif
+%{bindir}/%{name}-server
+%{bindir}/author-signature.xml
+%{bindir}/signature1.xml
+
+
+################################################################################
+# common... #
+################################################################################
+%prep
+%setup -q
+
+
+%build
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+%endif
+mkdir obj-arm-limux-qnueabi
+cd obj-arm-limux-qnueabi
+%cmake .. -DCMAKE_INSTALL_PREFIX=%{_prefix} %{?use_autostart} %{?use_gdbus} %{?test_client}
+#make %{?jobs:-j%jobs}
+
+
+%install
+cd obj-arm-limux-qnueabi
+%make_install
+%if 0%{!?use_autostart:1}
+ %__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/%{name}-server
+ chmod 755 %{buildroot}/etc/init.d/%{name}-server
+%endif
+mkdir -p %{buildroot}/usr/share/license
+cp -af %{_builddir}/%{name}-%{version}/packaging/%{name} %{buildroot}/usr/share/license/
+cp -af %{_builddir}/%{name}-%{version}/packaging/%{name}-common %{buildroot}/usr/share/license/
+cp -af %{_builddir}/%{name}-%{version}/packaging/%{name}-server %{buildroot}%{bindir}
+
+%define tizen_sign 1
+%define tizen_sign_base %{bindir}
+%define tizen_sign_level platform
+%define tizen_author_sign 1
+%define tizen_dist_sign 1
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(smartcard-daemon CXX)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ SRCS)
+### for private
+ADD_DEFINITIONS("-D__PRIVATE")
+
+FIND_PROGRAM(GDBUS_CODEGEN NAMES gdbus-codegen)
+EXEC_PROGRAM(${GDBUS_CODEGEN} ARGS
+ " \\
+ --generate-c-code ${CMAKE_CURRENT_SOURCE_DIR}/private/access-control-gdbus \\
+ --c-namespace SmartcardService\\
+ --interface-prefix org.tizen.SmartcardService. \\
+ ${CMAKE_CURRENT_SOURCE_DIR}/private/access-control-gdbus.xml \\
+ ")
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/private SRCS)
+##############
+
IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
SET(CMAKE_BUILD_TYPE "Release")
ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+# pkg config
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs_server REQUIRED glib-2.0 gobject-2.0 security-server vconf dlog dbus-glib-1)
+
+SET(PKG_MODULE glib-2.0 gio-2.0 gio-unix-2.0 security-server dlog)
+
+pkg_check_modules(pkgs_server REQUIRED ${PKG_MODULE})
FOREACH(flag ${pkgs_server_CFLAGS})
SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
MESSAGE("CHECK MODULE in ${PROJECT_NAME} ${pkgs_server_LDFLAGS}")
-IF("${USE_AUTOSTART}" STREQUAL "1")
- FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
- EXEC_PROGRAM("${DBUS_BINDING_TOOL}" ARGS "--prefix=smartcard_service ${CMAKE_CURRENT_SOURCE_DIR}/smartcard-service.xml --mode=glib-server --output=${CMAKE_CURRENT_SOURCE_DIR}/include/smartcard-service-binding.h")
- EXEC_PROGRAM("${DBUS_BINDING_TOOL}" ARGS "--prefix=smartcard_service ${CMAKE_CURRENT_SOURCE_DIR}/smartcard-service.xml --mode=glib-client --output=${CMAKE_CURRENT_SOURCE_DIR}/include/smartcard-service-glue.h")
-ENDIF()
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -fno-strict-aliasing -Wl,-zdefs -fvisibility=hidden")
+SET(ARM_CFLAGS "${ARM_CLAGS} -mapcs -mno-sched-prolog -mabi=aapcs-linux -Uarm -fno-common -fpic")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -fno-strict-aliasing -Wl,-zdefs -fvisibility=hidden -std=c++0x")
SET(ARM_CXXFLAGS "${ARM_CXXLAGS} -mapcs -mno-sched-prolog -mabi=aapcs-linux -Uarm -fno-common -fpic")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -fno-strict-aliasing -Wl,-zdefs -fvisibility=hidden")
-SET(ARM_CFLAGS "${ARM_CLAGS} -mapcs -mno-sched-prolog -mabi=aapcs-linux -Uarm -fno-common -fpic")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-
FIND_PROGRAM(UNAME NAMES uname)
EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
IF("${ARCH}" MATCHES "^arm.*")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARM_CFLAGS}")
ENDIF()
-ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DPREFIX=\"/usr/apps/smartcard-service-server\"")
ADD_DEFINITIONS("-DLOG_TAG=\"SMARTCARD_SERVICE_SERVER\"")
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_server_LDFLAGS} "-L../common" "-lsmartcard-service-common" "-pie -ldl")
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/apps/smartcard-service-server/bin)
IF("${USE_AUTOSTART}" STREQUAL "1")
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.tizen.smartcard_service.service DESTINATION share/dbus-1/services)
ENDIF()
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/smartcard-service-server.xml DESTINATION share/packages)
namespace smartcard_service_api
{
- gboolean ClientInstance::_getCertificationHashes(gpointer user_data)
- {
- gboolean result = false;
- ClientInstance *instance = (ClientInstance *)user_data;
-
- SignatureHelper::getCertificationHashes(instance->getPID(), instance->certHashes);
-
- return result;
- }
-
- void ClientInstance::setPID(int pid)
- {
- this->pid = pid;
-
- }
-
- ServiceInstance *ClientInstance::createService(unsigned int context)
+ ServiceInstance *ClientInstance::createService()
{
ServiceInstance *result = NULL;
- if ((result = getService(context)) == NULL)
+ result = new ServiceInstance(this);
+ if (result != NULL)
{
- result = new ServiceInstance(this, context);
- if (result != NULL)
- {
- mapServices.insert(make_pair(context, result));
- }
- else
- {
- SCARD_DEBUG_ERR("alloc failed");
- }
+ mapServices.insert(make_pair(result->getHandle(), result));
}
else
{
- SCARD_DEBUG_ERR("service already exist [%d]", context);
+ _ERR("alloc failed");
}
return result;
}
- ServiceInstance *ClientInstance::getService(unsigned int context)
+ ServiceInstance *ClientInstance::getService(unsigned int handle)
{
ServiceInstance *result = NULL;
map<unsigned int, ServiceInstance *>::iterator item;
- if ((item = mapServices.find(context)) != mapServices.end())
+ if ((item = mapServices.find(handle)) != mapServices.end())
{
result = item->second;
}
return result;
}
- void ClientInstance::removeService(unsigned int context)
+ void ClientInstance::removeService(unsigned int handle)
{
map<unsigned int, ServiceInstance *>::iterator item;
- if ((item = mapServices.find(context)) != mapServices.end())
+ if ((item = mapServices.find(handle)) != mapServices.end())
{
delete item->second;
mapServices.erase(item);
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;
- }
-
void ClientInstance::generateCertificationHashes()
{
- g_idle_add(_getCertificationHashes, (gpointer)this);
+ SignatureHelper::getCertificationHashes(getPID(), certHashes);
}
} /* namespace smartcard_service_api */
namespace smartcard_service_api
{
ServerChannel::ServerChannel(ServerSession *session, void *caller,
- int channelNum, Terminal *terminal)
- : Channel(session)
+ int channelNum, Terminal *terminal) :
+ Channel(session), terminal(terminal), caller(caller),
+ privilege(true)
{
- this->terminal = terminal;
- this->caller = caller;
this->channelNum = channelNum;
- this->privilege = true;
}
ServerChannel::~ServerChannel()
APDUHelper apdu;
int rv;
- if (isBasicChannel() == false)
+ if (isClosed() == false && isBasicChannel() == false)
{
/* close channel */
command = apdu.generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
+
+ _DBG("command [%d] : %s", command.size(), command.toString().c_str());
+
rv = terminal->transmitSync(command, result);
- if (rv == 0 && result.getLength() >= 2)
+ if (rv == 0 && result.size() >= 2)
{
ResponseHelper resp(result);
- if (resp.getStatus() == 0)
+ if (resp.getStatus() >= 0)
{
- SCARD_DEBUG("close success");
+ _DBG("close success");
}
else
{
- SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
+ _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
}
}
else
{
- SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
+ _ERR("select apdu is failed, rv [%d], length [%d]", rv, result.size());
}
- }
- channelNum = -1;
+ channelNum = -1;
+ }
}
- int ServerChannel::transmitSync(ByteArray command, ByteArray &result)
+ int ServerChannel::transmitSync(const ByteArray &command, ByteArray &result)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
int ret = -1;
APDUCommand helper;
+ ByteArray cmd;
if (isClosed() == true)
{
helper.getP1() == APDUCommand::P1_SELECT_BY_DF_NAME) ||
(helper.getINS() == APDUCommand::INS_MANAGE_CHANNEL))
{
- return -4; /* security reason */
+ return SCARD_ERROR_SECURITY_NOT_ALLOWED;
}
}
/* TODO : insert channel ID using atr information */
helper.setChannel(APDUCommand::CLA_CHANNEL_STANDARD, channelNum);
+ helper.getBuffer(cmd);
- helper.getBuffer(command);
+ _DBG("command [%d] : %s", cmd.size(), cmd.toString().c_str());
- SCARD_DEBUG("command [%d] : %s", command.getLength(), command.toString());
-
- ret = terminal->transmitSync(command, result);
- if (ret == 0 && ResponseHelper::getStatus(result) == 0)
- {
- /* store select response */
- if (helper.getINS() == APDUCommand::INS_SELECT_FILE)
- setSelectResponse(result);
- }
+ ret = terminal->transmitSync(cmd, result);
return ret;
}
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* standard library header */
-#include <stdio.h>
-#include <string.h>
-
-/* SLP library header */
-
-/* local header */
-#include "Debug.h"
-#include "Exception.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]");
-
- int count = 0;
- Message response(*msg);
- ByteArray info;
- ClientInstance *instance = NULL;
-
- response.param1 = 0;
- response.param2 = 0;
-
- /* load secure elements */
- resource->loadSecureElements();
-
- 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);
-
- /* generate certification hashes */
- instance->generateCertificationHashes();
- }
-
- /* create service */
- if (resource->createService(socket, (unsigned int)msg->userParam) != NULL)
- {
- response.error = SCARD_ERROR_OK;
-
- if ((count = resource->getReadersInformation(info)) > 0)
- {
- response.param1 = count;
- response.data = info;
- }
- else
- {
- SCARD_DEBUG("no secure elements");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("createClient failed");
-
- response.error = SCARD_ERROR_UNAVAILABLE;
- }
- }
- else
- {
- SCARD_DEBUG("client doesn't exist, socket [%d]", socket);
-
- response.error = SCARD_ERROR_UNAVAILABLE;
- }
-
- /* response to client */
- ServerIPC::getInstance()->sendMessage(socket, &response);
- }
- break;
-
- case Message::MSG_REQUEST_SHUTDOWN :
- {
- Message response(*msg);
-
- SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
-
- response.error = SCARD_ERROR_OK;
-
- resource->removeService(socket, msg->error/* service context */);
-
- /* response to client */
- ServerIPC::getInstance()->sendMessage(socket, &response);
- }
- break;
-
- case Message::MSG_REQUEST_OPEN_SESSION :
- {
- Message response(*msg);
- unsigned int handle = IntegerHandle::INVALID_HANDLE;
-
- SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
-
- if (resource->isValidReaderHandle(msg->param1))
- {
- vector<ByteArray> temp;
-
- handle = resource->createSession(socket, msg->error/* service context */, msg->param1, temp, msg->caller);
- if (handle != IntegerHandle::INVALID_HANDLE)
- {
- response.error = SCARD_ERROR_OK;
- }
- else
- {
- SCARD_DEBUG_ERR("createSession failed [%d]", handle);
- response.error = SCARD_ERROR_OUT_OF_MEMORY;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("request invalid reader handle [%d]", msg->param1);
- response.error = SCARD_ERROR_ILLEGAL_PARAM;
- }
-
- response.param1 = handle;
-
- /* response to client */
- ServerIPC::getInstance()->sendMessage(socket, &response);
- }
- break;
-
- case Message::MSG_REQUEST_CLOSE_SESSION :
- {
- Message response(*msg);
-
- SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
-
- response.param1 = 0;
- response.error = SCARD_ERROR_OK;
-
- 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);
- }
- break;
-
- case Message::MSG_REQUEST_OPEN_CHANNEL :
- {
- Message response(*msg);
-
- SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
-
- response.param1 = IntegerHandle::INVALID_HANDLE;
- response.param2 = 0;
- response.data.releaseBuffer();
-
- try
- {
- unsigned int channelID = IntegerHandle::INVALID_HANDLE;
-
- channelID = resource->createChannel(socket, msg->error/* service context */, msg->param2, msg->param1, msg->data);
- if (channelID != IntegerHandle::INVALID_HANDLE)
- {
- ServerChannel *temp;
-
- temp = (ServerChannel *)resource->getChannel(socket, msg->error/* service context */, channelID);
- if (temp != NULL)
- {
- response.param1 = channelID;
- response.param2 = temp->getChannelNumber();
- response.error = SCARD_ERROR_OK;
- response.data = temp->getSelectResponse();
- }
- else
- {
- SCARD_DEBUG_ERR("IS IT POSSIBLE??????????????????");
- response.error = SCARD_ERROR_UNKNOWN;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("channel is null.");
-
- /* set error value */
- response.error = SCARD_ERROR_UNAVAILABLE;
- }
- }
- catch (ExceptionBase &e)
- {
- response.error = e.getErrorCode();
- }
-
- /* response to client */
- ServerIPC::getInstance()->sendMessage(socket, &response);
- }
- break;
-
- case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
- {
- Message response(*msg);
-
- SCARD_DEBUG("[MSG_REQUEST_GET_CHANNEL_COUNT]");
-
- response.error = SCARD_ERROR_OK;
- 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 :
- {
- Message response(*msg);
-
- SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
-
- response.error = SCARD_ERROR_OK;
-
- 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);
- }
- break;
-
- case Message::MSG_REQUEST_GET_ATR :
- {
- int rv;
- Message response(*msg);
- ByteArray result;
- ServiceInstance *client = NULL;
-
- SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
-
- 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 = SCARD_ERROR_OK;
- }
- 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);
- response.error = SCARD_ERROR_UNAVAILABLE;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("getClient failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
- response.error = SCARD_ERROR_UNAVAILABLE;
- }
-
- /* response to client */
- ServerIPC::getInstance()->sendMessage(socket, &response);
- }
- break;
-
- case Message::MSG_REQUEST_TRANSMIT :
- {
- int rv;
- Message response(*msg);
- ByteArray result;
- Channel *channel = NULL;
-
- SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
-
- 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 = SCARD_ERROR_OK;
- }
- 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.error = SCARD_ERROR_UNAVAILABLE;
- }
-
- /* response to client */
- ServerIPC::getInstance()->sendMessage(socket, &response);
- }
- break;
-
- case Message::MSG_OPERATION_RELEASE_CLIENT :
- {
- SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
-
- resource->removeClient(msg->param1);
- SCARD_DEBUG("remain client [%d]", resource->getClientCount());
- }
-#ifdef USE_AUTOSTART
- if (resource->getClientCount() == 0)
- {
- SCARD_DEBUG("There is no client. shutting down service");
- g_main_loop_quit((GMainLoop *)resource->getMainLoopInstance());
- }
-#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, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* standard library header */
+#include <unistd.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <vector>
+#include <string>
+#include <sys/socket.h>
+
+/* SLP library header */
+#ifdef USER_SPACE_SMACK
+#include "security-server.h"
+#endif
+
+/* local header */
+#include "smartcard-types.h"
+#include "Debug.h"
+#include "ByteArray.h"
+#include "ServerResource.h"
+#include "GDBusHelper.h"
+#include "ServerGDBus.h"
+
+using namespace std;
+
+#ifdef __PRIVATE
+extern "C" bool smartcard_service_init_access_control(void *connection);
+extern "C" void smartcard_service_deinit_access_control();
+#endif
+
+namespace smartcard_service_api
+{
+ GDBusDispatcher::GDBusDispatcher() : Synchronous()
+ {
+ }
+
+ GDBusDispatcher::~GDBusDispatcher()
+ {
+ }
+
+ GDBusDispatcher &GDBusDispatcher::getInstance()
+ {
+ static GDBusDispatcher dispatcher;
+
+ return dispatcher;
+ }
+
+ void GDBusDispatcher::_push(dispatcher_cb_t cb,
+ const vector<void *> ¶ms)
+ {
+ syncLock();
+
+ q.push(make_pair(cb, params));
+ _INFO("request pushed, count [%d]", q.size());
+
+ if (q.size() == 1) {
+ /* start dispatch */
+ _INFO("start dispatcher");
+ g_idle_add(&GDBusDispatcher::dispatch, this);
+ }
+
+ syncUnlock();
+ }
+
+ void GDBusDispatcher::push(dispatcher_cb_t cb,
+ const vector<void *> ¶ms)
+ {
+ GDBusDispatcher::getInstance()._push(cb, params);
+ }
+
+ gboolean GDBusDispatcher::dispatch(gpointer user_data)
+ {
+ GDBusDispatcher *dispatcher = (GDBusDispatcher *)user_data;
+ gboolean result = false;
+
+ _BEGIN();
+
+ dispatcher->syncLock();
+
+ pair<dispatcher_cb_t, vector<void *> > &job =
+ dispatcher->q.front();
+
+ dispatcher->syncUnlock();
+
+ job.first(job.second);
+
+ dispatcher->syncLock();
+
+ dispatcher->q.pop();
+ if (dispatcher->q.size() > 0) {
+ _INFO("remaining messages : %d", dispatcher->q.size());
+
+ result = true;
+ } else {
+ _INFO("dispatch finished");
+ }
+
+ dispatcher->syncUnlock();
+
+ _END();
+
+ return result;
+ }
+
+ ServerGDBus::ServerGDBus() : dbus_proxy(NULL), connection(NULL),
+ seService(NULL), reader(NULL), session(NULL), channel(NULL)
+ {
+ }
+
+ ServerGDBus::~ServerGDBus()
+ {
+ deinit();
+ }
+
+ ServerGDBus &ServerGDBus::getInstance()
+ {
+ static ServerGDBus serverGDBus;
+
+ return serverGDBus;
+ }
+
+ static void name_owner_changed(GDBusProxy *proxy,
+ const gchar *name, const gchar *old_owner,
+ const gchar *new_owner, void *user_data)
+ {
+ if (name == NULL || old_owner == NULL || new_owner == NULL) {
+ _ERR("invalid parameter");
+ return;
+ }
+
+ if (strlen(new_owner) == 0) {
+ ClientInstance *client;
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ client = resource.getClient(old_owner);
+ if (client != NULL) {
+ _INFO("terminated client, pid [%d]", client->getPID());
+ resource.removeClient(old_owner);
+
+ resource.finish();
+ }
+ }
+ }
+
+ static void _on_name_owner_changed(GDBusConnection *connection,
+ const gchar *sender_name, const gchar *object_path,
+ const gchar *interface_name, const gchar *signal_name,
+ GVariant *parameters, gpointer user_data)
+ {
+ gchar *name;
+ gchar *old_owner;
+ gchar *new_owner;
+
+ g_variant_get(parameters,
+ "(sss)",
+ &name,
+ &old_owner,
+ &new_owner);
+
+ name_owner_changed((GDBusProxy *)connection,
+ name, old_owner, new_owner, user_data);
+ }
+
+ bool ServerGDBus::_init()
+ {
+ GError *error = NULL;
+
+ /* init default context */
+ dbus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL, /* GDBusInterfaceInfo */
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ NULL, /* GCancellable */
+ &error);
+ if (dbus_proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+
+ return false;
+ }
+
+ /* subscribe signal */
+ g_dbus_connection_signal_subscribe(connection,
+ "org.freedesktop.DBus", /* bus name */
+ "org.freedesktop.DBus", /* interface */
+ "NameOwnerChanged", /* member */
+ "/org/freedesktop/DBus", /* path */
+ NULL, /* arg0 */
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ _on_name_owner_changed,
+ NULL, NULL);
+
+ return true;
+ }
+
+ void ServerGDBus::_deinit()
+ {
+ if (dbus_proxy != NULL) {
+ g_object_unref(dbus_proxy);
+ dbus_proxy = NULL;
+ }
+ }
+
+ bool ServerGDBus::init()
+ {
+ GError *error = NULL;
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection != NULL) {
+ } else {
+ _ERR("Can not get connection %s", error->message);
+ g_error_free(error);
+
+ return false;
+ }
+
+ _init();
+
+ initSEService();
+ initReader();
+ initSession();
+ initChannel();
+#ifdef __PRIVATE
+ smartcard_service_init_access_control(connection);
+#endif
+ return true;
+ }
+
+ void ServerGDBus::deinit()
+ {
+#ifdef __PRIVATE
+ smartcard_service_deinit_access_control();
+#endif
+ deinitChannel();
+ deinitSession();
+ deinitReader();
+ deinitSEService();
+
+ _deinit();
+
+ if (connection != NULL) {
+ g_object_unref(connection);
+ connection = NULL;
+ }
+ }
+
+ static gboolean _call_get_connection_unix_process_id_sync(
+ GDBusProxy *proxy, const gchar *arg_name, guint *out_pid,
+ GCancellable *cancellable, GError **error) {
+ GVariant *_ret;
+
+ _ret = g_dbus_proxy_call_sync(proxy,
+ "GetConnectionUnixProcessID",
+ g_variant_new("(s)", arg_name),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, cancellable, error);
+ if (_ret != NULL) {
+ g_variant_get(_ret, "(u)", out_pid);
+ g_variant_unref(_ret);
+ }
+
+ return _ret != NULL;
+ }
+
+ pid_t ServerGDBus::getPID(const char *name)
+ {
+ guint pid = 0;
+ GError *error = NULL;
+
+ if (_call_get_connection_unix_process_id_sync(
+ (GDBusProxy *)dbus_proxy, name,
+ &pid, NULL, &error) == true) {
+ } else {
+ _ERR("_g_freedesktop_dbus_call_get_connection_unix_process_id_sync failed : %s", error->message);
+ g_error_free(error);
+ }
+
+ return pid;
+ }
+
+ static bool _is_authorized_request(GDBusMethodInvocation *invocation,
+ const char *rights)
+ {
+ bool result = true;
+#ifdef USER_SPACE_SMACK
+ pid_t pid;
+ const char *name;
+ ClientInstance *instance;
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ instance = ServerResource::getInstance().getClient(name);
+ if (instance != NULL) {
+ pid = instance->getPID();
+ } else {
+ pid = ServerGDBus::getInstance().getPID(name);
+ }
+
+ result = (security_server_check_privilege_by_pid(
+ pid,
+ "smartcard-service",
+ rights) == SECURITY_SERVER_API_SUCCESS);
+#endif
+ return result;
+ }
+
+ /* SEService *
+ *
+ *
+ */
+ static GVariant *_reader_to_variant(
+ vector<pair<unsigned int, string> > &readers)
+ {
+ GVariantBuilder builder;
+ uint32_t i;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
+
+ for (i = 0; i < readers.size(); i++) {
+ g_variant_builder_add(&builder, "(us)",
+ readers[i].first, readers[i].second.c_str());
+ }
+
+ return g_variant_builder_end(&builder);
+ }
+
+ static gboolean __process_se_service(SmartcardServiceSeService *object,
+ GDBusMethodInvocation *invocation,
+ void *user_data)
+ {
+ gint result = SCARD_ERROR_OK;
+ GVariant *readers = NULL;
+ vector<pair<unsigned int, string> > list;
+ unsigned int handle = IntegerHandle::INVALID_HANDLE;
+ const char *name;
+ pid_t pid;
+
+ _INFO("[MSG_REQUEST_READERS]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ /* load secure elements */
+ resource.loadSecureElements();
+
+ pid = ServerGDBus::getInstance().getPID(name);
+
+ _DBG("service requested, pid [%d]", pid);
+
+ if (pid > 0) {
+ ClientInstance *instance;
+
+ instance = resource.getClient(name);
+ if (instance == NULL) {
+ _INFO("create client instance, pid [%d]", pid);
+
+ resource.createClient(name, pid);
+
+ instance = resource.getClient(name);
+ if (instance != NULL) {
+ /* generate certification hashes */
+ instance->generateCertificationHashes();
+ } else {
+ _ERR("createClient failed");
+ }
+ }
+
+ if (instance != NULL) {
+ ServiceInstance *service;
+
+ /* create service */
+ service = resource.createService(name);
+ if (service != NULL) {
+
+ handle = service->getHandle();
+ resource.getReaders(list);
+
+ if (list.size() == 0) {
+ _INFO("no secure elements");
+ }
+ } else {
+ _ERR("createService failed");
+
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ _ERR("client doesn't exist, pid [%d]", pid);
+
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ _ERR("invalid pid, [%d]", pid);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ readers = _reader_to_variant(list);
+
+ /* response to client */
+ smartcard_service_se_service_complete_se_service(object,
+ invocation, result, handle, readers);
+
+ return true;
+ }
+
+ static void _process_se_service(vector<void *> ¶ms)
+ {
+ SmartcardServiceSeService *object;
+ GDBusMethodInvocation *invocation;
+ void *user_data;
+
+ if (params.size() != 3) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceSeService *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ user_data = params[2];
+
+ __process_se_service(object, invocation, user_data);
+
+ g_object_unref(object);
+ g_object_unref(invocation);
+ }
+
+ static gboolean _handle_se_service(SmartcardServiceSeService *object,
+ GDBusMethodInvocation *invocation,
+ void *user_data)
+ {
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "r") == true) {
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)user_data);
+
+ GDBusDispatcher::push(_process_se_service, params);
+ } else {
+ vector<pair<unsigned int, string> > list;
+
+ _ERR("access denied");
+
+ /* response to client */
+ smartcard_service_se_service_complete_se_service(object,
+ invocation,
+ SCARD_ERROR_SECURITY_NOT_ALLOWED,
+ IntegerHandle::INVALID_HANDLE,
+ _reader_to_variant(list));
+ }
+
+ return true;
+ }
+
+ static gboolean __process_shutdown(SmartcardServiceSeService *object,
+ GDBusMethodInvocation *invocation,
+ guint handle, void *user_data)
+ {
+ const char *name;
+
+ _INFO("[MSG_REQUEST_SHUTDOWN]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ resource.removeService(name, handle);
+
+ /* response to client */
+ smartcard_service_se_service_complete_shutdown(object,
+ invocation, SCARD_ERROR_OK);
+
+ /* terminate */
+ resource.finish();
+
+ return true;
+ }
+
+ static void _process_shutdown(vector<void *> ¶ms)
+ {
+ SmartcardServiceSeService *object;
+ GDBusMethodInvocation *invocation;
+ guint handle;
+ void *user_data;
+
+ if (params.size() != 4) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceSeService *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ handle = (guint)params[2];
+ user_data = params[3];
+
+ __process_shutdown(object, invocation, handle, user_data);
+
+ g_object_unref(object);
+ g_object_unref(invocation);
+ }
+
+ static gboolean _handle_shutdown(SmartcardServiceSeService *object,
+ GDBusMethodInvocation *invocation,
+ guint handle,
+ void *user_data)
+ {
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "r") == true) {
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)handle);
+ params.push_back(user_data);
+
+ GDBusDispatcher::push(_process_shutdown, params);
+ } else {
+ _ERR("access denied");
+
+ /* response to client */
+ smartcard_service_se_service_complete_shutdown(object,
+ invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
+ }
+
+ return true;
+ }
+
+ bool ServerGDBus::initSEService()
+ {
+ GError *error = NULL;
+
+ seService = smartcard_service_se_service_skeleton_new();
+
+ g_signal_connect(seService,
+ "handle-se-service",
+ G_CALLBACK(_handle_se_service),
+ this);
+
+ g_signal_connect(seService,
+ "handle-shutdown",
+ G_CALLBACK(_handle_shutdown),
+ this);
+
+ if (g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(seService),
+ connection,
+ "/org/tizen/SmartcardService/SeService",
+ &error) == false)
+ {
+ _ERR("Can not skeleton_export %s", error->message);
+
+ g_error_free(error);
+ g_object_unref(seService);
+ seService = NULL;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void ServerGDBus::deinitSEService()
+ {
+ if (seService != NULL) {
+ g_object_unref(seService);
+ seService = NULL;
+ }
+ }
+
+ void ServerGDBus::emitReaderInserted(unsigned int reader_id,
+ const char *reader_name)
+ {
+ smartcard_service_se_service_emit_reader_inserted(
+ SMARTCARD_SERVICE_SE_SERVICE(seService),
+ reader_id, reader_name);
+ }
+
+ void ServerGDBus::emitReaderRemoved(unsigned int reader_id,
+ const char *reader_name)
+ {
+ smartcard_service_se_service_emit_reader_removed(
+ SMARTCARD_SERVICE_SE_SERVICE(seService),
+ reader_id, reader_name);
+ }
+
+ /* Reader *
+ *
+ *
+ */
+ static gboolean __process_open_session(SmartcardServiceReader *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint reader_id, void *user_data)
+ {
+ unsigned int handle = IntegerHandle::INVALID_HANDLE;
+ int result;
+ const char *name;
+
+ _INFO("[MSG_REQUEST_OPEN_SESSION]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ if (resource.isValidReaderHandle(reader_id)) {
+ vector<ByteArray> temp;
+
+ handle = resource.createSession(name,
+ service_id,
+ reader_id,
+ temp,
+ (void *)NULL);
+ if (handle != IntegerHandle::INVALID_HANDLE) {
+ result = SCARD_ERROR_OK;
+ } else {
+ _ERR("createSession failed [%d]", handle);
+
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ _ERR("request invalid reader handle [%d]", reader_id);
+
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ /* response to client */
+ smartcard_service_reader_complete_open_session(object,
+ invocation, result, handle);
+
+ return true;
+ }
+
+ static void _process_open_session(vector<void *> ¶ms)
+ {
+ SmartcardServiceReader *object;
+ GDBusMethodInvocation *invocation;
+ guint service_id;
+ guint reader_id;
+ void *user_data;
+
+ if (params.size() != 5) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceReader *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ service_id = (guint)params[2];
+ reader_id = (guint)params[3];
+ user_data = params[4];
+
+ __process_open_session(object, invocation, service_id,
+ reader_id, user_data);
+
+ g_object_unref(object);
+ g_object_unref(invocation);
+ }
+
+ static gboolean _handle_open_session(SmartcardServiceReader *object,
+ GDBusMethodInvocation *invocation,
+ guint service_id,
+ guint reader_id, void *user_data)
+ {
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "r") == true) {
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)service_id);
+ params.push_back((void *)reader_id);
+ params.push_back(user_data);
+
+ GDBusDispatcher::push(_process_open_session, params);
+ } else {
+ _ERR("access denied");
+
+ /* response to client */
+ smartcard_service_reader_complete_open_session(object,
+ invocation,
+ SCARD_ERROR_SECURITY_NOT_ALLOWED,
+ IntegerHandle::INVALID_HANDLE);
+ }
+
+ return true;
+ }
+
+ bool ServerGDBus::initReader()
+ {
+ GError *error = NULL;
+
+ reader = smartcard_service_reader_skeleton_new();
+
+ g_signal_connect(reader,
+ "handle-open-session",
+ G_CALLBACK(_handle_open_session),
+ this);
+
+ if (g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(reader),
+ connection,
+ "/org/tizen/SmartcardService/Reader",
+ &error) == false)
+ {
+ _ERR("Can not skeleton_export %s", error->message);
+
+ g_error_free(error);
+ g_object_unref(reader);
+ reader = NULL;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void ServerGDBus::deinitReader()
+ {
+ if (reader != NULL) {
+ g_object_unref(reader);
+ reader = NULL;
+ }
+ }
+
+ /* Session *
+ *
+ *
+ */
+ static gboolean __process_close_session(SmartcardServiceSession *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint session_id, void *user_data)
+ {
+ const char *name;
+
+ _INFO("[MSG_REQUEST_CLOSE_SESSION]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ if (resource.isValidSessionHandle(name, service_id,
+ session_id)) {
+ resource.removeSession(name, service_id,
+ session_id);
+ } else {
+ _ERR("invalid parameters");
+ }
+
+ /* response to client */
+ smartcard_service_session_complete_close_session(object,
+ invocation, SCARD_ERROR_OK);
+
+ return true;
+ }
+
+ static void _process_close_session(vector<void *> ¶ms)
+ {
+ SmartcardServiceSession *object;
+ GDBusMethodInvocation *invocation;
+ guint service_id;
+ guint session_id;
+ void *user_data;
+
+ if (params.size() != 5) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceSession *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ service_id = (guint)params[2];
+ session_id = (guint)params[3];
+ user_data = params[4];
+
+ __process_close_session(object, invocation, service_id,
+ session_id, user_data);
+
+ g_object_unref(object);
+ g_object_unref(invocation);
+ }
+
+ static gboolean _handle_close_session(SmartcardServiceSession *object,
+ GDBusMethodInvocation *invocation,
+ guint service_id,
+ guint session_id, void *user_data)
+ {
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "r") == true) {
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)service_id);
+ params.push_back((void *)session_id);
+ params.push_back(user_data);
+
+ GDBusDispatcher::push(_process_close_session, params);
+ } else {
+ _ERR("access denied");
+
+ /* response to client */
+ smartcard_service_session_complete_close_session(object,
+ invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
+ }
+
+ return true;
+ }
+
+ static gboolean __process_get_atr(SmartcardServiceSession *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint session_id, void *user_data)
+ {
+ int result;
+ ByteArray resp;
+ GVariant *atr = NULL;
+ const char *name;
+ ServiceInstance *client = NULL;
+
+ _INFO("[MSG_REQUEST_GET_ATR]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ client = resource.getService(name, service_id);
+ if (client != NULL) {
+ Terminal *terminal;
+
+ terminal = client->getTerminal(session_id);
+ if (terminal != NULL) {
+ if (terminal->open() == true) {
+ result = terminal->getATRSync(resp);
+ if (result < SCARD_ERROR_OK) {
+ _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
+ }
+
+ terminal->close();
+ } else {
+ _ERR("terminal->open failed");
+
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+ } else {
+ _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
+
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+ } else {
+ _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
+
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+
+ atr = GDBusHelper::convertByteArrayToVariant(resp);
+
+ /* response to client */
+ smartcard_service_session_complete_get_atr(object, invocation,
+ result, atr);
+
+ return true;
+ }
+
+ static void _process_get_atr(vector<void *> ¶ms)
+ {
+ SmartcardServiceSession *object;
+ GDBusMethodInvocation *invocation;
+ guint service_id;
+ guint session_id;
+ void *user_data;
+
+ if (params.size() != 5) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceSession *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ service_id = (guint)params[2];
+ session_id = (guint)params[3];
+ user_data = params[4];
+
+ __process_get_atr(object, invocation, service_id,
+ session_id, user_data);
+
+ g_object_unref(object);
+ g_object_unref(invocation);
+ }
+
+ static gboolean _handle_get_atr(SmartcardServiceSession *object,
+ GDBusMethodInvocation *invocation,
+ guint service_id,
+ guint session_id, void *user_data)
+ {
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "r") == true) {
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)service_id);
+ params.push_back((void *)session_id);
+ params.push_back(user_data);
+
+ GDBusDispatcher::push(_process_get_atr, params);
+ } else {
+ ByteArray resp;
+
+ _ERR("access denied");
+
+ /* response to client */
+ smartcard_service_session_complete_get_atr(
+ object,
+ invocation,
+ SCARD_ERROR_SECURITY_NOT_ALLOWED,
+ GDBusHelper::convertByteArrayToVariant(resp));
+ }
+
+ return true;
+ }
+
+ static gboolean __process_open_channel(SmartcardServiceSession *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
+ {
+ int channelNum = -1;
+ int result = SCARD_ERROR_UNKNOWN;
+ ByteArray resp;
+ GVariant *response = NULL;
+ unsigned int channelID = IntegerHandle::INVALID_HANDLE;
+ const char *name;
+
+ _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
+ _INFO("P2 is %x", P2);
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ try
+ {
+ ByteArray tempAid;
+
+ GDBusHelper::convertVariantToByteArray(aid,
+ tempAid);
+
+ channelID = resource.createChannel(name,
+ service_id, session_id, type, tempAid);
+ if (channelID != IntegerHandle::INVALID_HANDLE) {
+ ServerChannel *temp;
+
+ temp = (ServerChannel *)resource.getChannel(
+ name, service_id, channelID);
+ if (temp != NULL) {
+ resp = temp->getSelectResponse();
+ channelNum = temp->getChannelNumber();
+ result = SCARD_ERROR_OK;
+ }
+ else{
+ _ERR("getChannel is failed");
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+ } else {
+ _ERR("channel is null.");
+
+ /* set error value */
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+ }
+ catch (ExceptionBase &e)
+ {
+ result = e.getErrorCode();
+ }
+
+ response = GDBusHelper::convertByteArrayToVariant(resp);
+
+ /* response to client */
+ smartcard_service_session_complete_open_channel(object,
+ invocation, result, channelID, channelNum, response);
+
+ return true;
+ }
+
+ static void _process_open_channel(vector<void *> ¶ms)
+ {
+ SmartcardServiceSession *object;
+ GDBusMethodInvocation *invocation;
+ guint service_id;
+ guint session_id;
+ guint type;
+ guint8 P2;
+ GVariant *aid;
+ void *user_data;
+
+ if (params.size() != 8) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceSession *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ service_id = (guint)params[2];
+ session_id = (guint)params[3];
+ type = (guint)params[4];
+ aid = (GVariant *)params[5];
+ P2 = (guint8)((int)params[6]);
+ user_data = params[7];
+
+ __process_open_channel(object, invocation, service_id,
+ session_id, type, aid, P2, user_data);
+
+ g_object_unref(object);
+ g_object_unref(invocation);
+ g_variant_unref(aid);
+ }
+
+ static gboolean _handle_open_channel(SmartcardServiceSession *object,
+ GDBusMethodInvocation *invocation,
+ guint service_id,
+ guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
+ {
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "rw") == true) {
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)service_id);
+ params.push_back((void *)session_id);
+ params.push_back((void *)type);
+
+ g_variant_ref(aid);
+ params.push_back((void *)aid);
+ params.push_back((void *)((int)P2));
+ params.push_back(user_data);
+
+ GDBusDispatcher::push(_process_open_channel, params);
+ } else {
+ ByteArray resp;
+
+ _ERR("access denied");
+
+ /* response to client */
+ smartcard_service_session_complete_open_channel(object,
+ invocation,
+ SCARD_ERROR_SECURITY_NOT_ALLOWED,
+ IntegerHandle::INVALID_HANDLE,
+ -1,
+ GDBusHelper::convertByteArrayToVariant(resp));
+ }
+
+ return true;
+ }
+
+ bool ServerGDBus::initSession()
+ {
+ GError *error = NULL;
+
+ session = smartcard_service_session_skeleton_new();
+
+ g_signal_connect(session,
+ "handle-close-session",
+ G_CALLBACK(_handle_close_session),
+ this);
+
+ g_signal_connect(session,
+ "handle-get-atr",
+ G_CALLBACK(_handle_get_atr),
+ this);
+
+ g_signal_connect(session,
+ "handle-open-channel",
+ G_CALLBACK(_handle_open_channel),
+ this);
+
+ if (g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(session),
+ connection,
+ "/org/tizen/SmartcardService/Session",
+ &error) == false)
+ {
+ _ERR("Can not skeleton_export %s", error->message);
+
+ g_error_free(error);
+ g_object_unref(session);
+ session = NULL;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void ServerGDBus::deinitSession()
+ {
+ if (session != NULL) {
+ g_object_unref(session);
+ session = NULL;
+ }
+ }
+
+ /* Channel *
+ *
+ *
+ */
+ static gboolean __process_close_channel(SmartcardServiceChannel *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint channel_id, void *user_data)
+ {
+ int result;
+ const char *name;
+
+ _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ resource.removeChannel(name, service_id, channel_id);
+
+ result = SCARD_ERROR_OK;
+
+ /* response to client */
+ smartcard_service_channel_complete_close_channel(object,
+ invocation, result);
+
+ return true;
+ }
+
+ static void _process_close_channel(vector<void *> ¶ms)
+ {
+ SmartcardServiceChannel *object;
+ GDBusMethodInvocation *invocation;
+ guint service_id;
+ guint channel_id;
+ void *user_data;
+
+ if (params.size() != 5) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceChannel *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ service_id = (guint)params[2];
+ channel_id = (guint)params[3];
+ user_data = params[4];
+
+ __process_close_channel(object, invocation, service_id,
+ channel_id, user_data);
+
+ g_object_unref(object);
+ g_object_unref(invocation);
+ }
+
+ static gboolean _handle_close_channel(SmartcardServiceChannel *object,
+ GDBusMethodInvocation *invocation,
+ guint service_id, guint channel_id, void *user_data)
+ {
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "r") == true) {
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)service_id);
+ params.push_back((void *)channel_id);
+ params.push_back(user_data);
+
+ GDBusDispatcher::push(_process_close_channel, params);
+ } else {
+ _ERR("access denied");
+
+ /* response to client */
+ smartcard_service_channel_complete_close_channel(
+ object,
+ invocation,
+ SCARD_ERROR_SECURITY_NOT_ALLOWED);
+ }
+
+ return true;
+ }
+
+ static gboolean __process_transmit(SmartcardServiceChannel *object,
+ GDBusMethodInvocation *invocation,
+ guint service_id,
+ guint channel_id,
+ GVariant *command,
+ void *user_data)
+ {
+ int result;
+ Channel *channel = NULL;
+ ByteArray resp;
+ GVariant *response = NULL;
+ const char *name;
+
+ _INFO("[MSG_REQUEST_TRANSMIT]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ channel = resource.getChannel(name, service_id, channel_id);
+ if (channel != NULL) {
+ int rv;
+ ByteArray cmd;
+
+ GDBusHelper::convertVariantToByteArray(command, cmd);
+
+ rv = channel->transmitSync(cmd, resp);
+ if (rv == 0) {
+ result = SCARD_ERROR_OK;
+ } else {
+ _ERR("transmit failed [%d]", rv);
+
+ result = rv;
+ }
+ } else {
+ _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
+
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+
+ response = GDBusHelper::convertByteArrayToVariant(resp);
+
+ /* response to client */
+ smartcard_service_channel_complete_transmit(object, invocation,
+ result, response);
+
+ return true;
+ }
+
+ static void _process_transmit(vector<void *> ¶ms)
+ {
+ SmartcardServiceChannel *object;
+ GDBusMethodInvocation *invocation;
+ guint service_id;
+ guint channel_id;
+ GVariant *command;
+ void *user_data;
+
+ if (params.size() != 6) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceChannel *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ service_id = (guint)params[2];
+ channel_id = (guint)params[3];
+ command = (GVariant *)params[4];
+ user_data = params[5];
+
+ __process_transmit(object, invocation, service_id,
+ channel_id, command, user_data);
+
+ g_object_unref(object);
+ g_object_unref(invocation);
+ g_object_unref(command);
+ }
+
+ static gboolean _handle_transmit(SmartcardServiceChannel *object,
+ GDBusMethodInvocation *invocation,
+ guint service_id,
+ guint channel_id,
+ GVariant *command,
+ void *user_data)
+ {
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "r") == true) {
+ /* enqueue message */
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)service_id);
+ params.push_back((void *)channel_id);
+
+ g_object_ref(command);
+ params.push_back((void *)command);
+
+ params.push_back(user_data);
+
+ GDBusDispatcher::push(_process_transmit, params);
+ } else {
+ ByteArray resp;
+
+ _ERR("access denied");
+
+ /* response to client */
+ smartcard_service_channel_complete_transmit(object,
+ invocation,
+ SCARD_ERROR_SECURITY_NOT_ALLOWED,
+ GDBusHelper::convertByteArrayToVariant(resp));
+ }
+
+ return true;
+ }
+
+ bool ServerGDBus::initChannel()
+ {
+ GError *error = NULL;
+
+ channel = smartcard_service_channel_skeleton_new();
+
+ g_signal_connect(channel,
+ "handle-close-channel",
+ G_CALLBACK(_handle_close_channel),
+ this);
+
+ g_signal_connect(channel,
+ "handle-transmit",
+ G_CALLBACK(_handle_transmit),
+ this);
+
+ if (g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(channel),
+ connection,
+ "/org/tizen/SmartcardService/Channel",
+ &error) == false)
+ {
+ _ERR("Can not skeleton_export %s", error->message);
+
+ g_error_free(error);
+ g_object_unref(channel);
+ channel = NULL;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void ServerGDBus::deinitChannel()
+ {
+ if (channel != NULL) {
+ g_object_unref(channel);
+ channel = NULL;
+ }
+ }
+} /* namespace smartcard_service_api */
+++ /dev/null
-/*
- * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* standard library header */
-#include <string.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-/* SLP library header */
-#ifdef SECURITY_SERVER
-#include "security-server.h"
-#endif
-
-/* local header */
-#include "Debug.h"
-#include "ServerIPC.h"
-#include "ServerResource.h"
-#include "ServerDispatcher.h"
-
-#ifndef EXTERN_API
-#define EXTERN_API __attribute__((visibility("default")))
-#endif
-
-namespace smartcard_service_api
-{
- ServerIPC::ServerIPC():IPCHelper()
- {
- SCARD_BEGIN();
-
- setDispatcher(ServerDispatcher::getInstance());
-
- SCARD_END();
- }
-
- ServerIPC::~ServerIPC()
- {
- }
-
- ServerIPC *ServerIPC::getInstance()
- {
- static ServerIPC instance;
-
- return &instance;
- }
-
- Message *ServerIPC::retrieveMessage(int socket)
- {
- ByteArray buffer;
- Message *msg = NULL;
-
- SCARD_BEGIN();
-
- buffer = IPCHelper::retrieveBuffer(socket);
- if (buffer.getLength() > 0)
- {
-#ifdef SECURITY_SERVER
- ByteArray cookie;
- int result, gid;
-
- if (buffer.getLength() < 20)
- return msg;
-
- cookie.setBuffer(buffer.getBuffer(), 20);
-
- gid = security_server_get_gid("smartcard-daemon");
- if ((result = security_server_check_privilege(cookie.getBuffer(), gid)) != SECURITY_SERVER_API_SUCCESS)
- {
- SCARD_DEBUG_ERR("security_server_check_privilege failed [%d]", result);
- return msg;
- }
-#endif
- msg = new Message();
- if (msg != NULL)
- {
- msg->deserialize(buffer);
- }
- else
- {
- SCARD_DEBUG_ERR("alloc failed");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("retrieveBuffer failed ");
- }
-
- SCARD_END();
-
- return msg;
- }
-
- 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 bond 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()
- {
- destroyListenSocket();
-
- 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;
- int peerSocket = g_io_channel_unix_get_fd((GIOChannel *)channel);
-
- SCARD_DEBUG("client socket is closed, socket [%d]", peerSocket);
-
- /* push messsage to dispatcher */
- 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;
-
- /* read message */
- if ((msg = retrieveMessage(peerSocket)) != NULL)
- {
- DispatcherMsg dispMsg(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 */
-
-using namespace smartcard_service_api;
-
-EXTERN_API void server_ipc_create_listen_socket()
-{
- ServerIPC *ipc = ServerIPC::getInstance();
-
- ipc->createListenSocket();
-}
#include "Debug.h"
#include "ServerSEService.h"
#include "ServerReader.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
namespace smartcard_service_api
{
- ServerReader::ServerReader(ServerSEService *seService, char *name, Terminal *terminal) :
- ReaderHelper()
+ ServerReader::ServerReader(ServerSEService *seService,
+ const char *name, Terminal *terminal) : ReaderHelper()
{
- unsigned int length = 0;
-
- acList = NULL;
-
- if (seService == NULL || name == NULL || strlen(name) == 0 || terminal == NULL)
+ if (seService == NULL || name == NULL ||
+ strlen(name) == 0 || terminal == NULL)
{
- SCARD_DEBUG_ERR("invalid param");
+ _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");
- }
+ this->name = name;
}
ServerReader::~ServerReader()
{
closeSessions();
-
- if (acList != NULL)
- {
- delete acList;
- acList = NULL;
- }
-
- if (adminChannel != NULL)
- {
- delete adminChannel;
- adminChannel = NULL;
- }
}
void ServerReader::closeSessions()
sessions.clear();
}
- AccessControlList *ServerReader::getAccessControlList()
- {
- if (acList == NULL)
- {
- /* load access control */
- acList = new GPSEACL();
- if (acList != NULL)
- {
- acList->loadACL(adminChannel);
- }
- else
- {
- SCARD_DEBUG_ERR("alloc failed");
- }
- }
-
- return acList;
- }
-
ServerSession *ServerReader::openSessionSync()
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
return openSessionSync(temp, NULL);
}
- ServerSession *ServerReader::openSessionSync(vector<ByteArray> &certHashes, void *caller)
+ ServerSession *ServerReader::openSessionSync(const vector<ByteArray> &certHashes, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
ServerSession *session = NULL;
#include "TerminalInterface.h"
#include "APDUHelper.h"
#include "SignatureHelper.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
+#include "PKCS15.h"
+#include "ServerGDBus.h"
+#include "smartcard-daemon.h"
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
#endif
+using namespace std;
+
namespace smartcard_service_api
{
unsigned int IntegerHandle::newHandle = 0;
while (!result.second);
}
- SCARD_DEBUG("assign handle : newHandle [%d]", newHandle);
+ _DBG("assign handle : newHandle [%d]", newHandle);
return newHandle;
}
void IntegerHandle::releaseHandle(unsigned int handle)
{
- SCARD_DEBUG("will be released : Handle [%d]", handle);
+ _DBG("will be released : Handle [%d]", handle);
SCOPE_LOCK(mutexLock)
{
#define OMAPI_SE_PATH "/usr/lib/se"
- ServerResource::ServerResource()
- : mainLoop(NULL), seLoaded(false)
+ ServerResource::ServerResource() : seLoaded(false)
{
- SCARD_BEGIN();
-
- serverIPC = ServerIPC::getInstance();
- serverDispatcher = ServerDispatcher::getInstance();
-
- SCARD_END();
+ _BEGIN();
+ _END();
}
ServerResource::~ServerResource()
return serverResource;
}
- bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
+ bool ServerResource::createClient(const char *name, pid_t pid)
{
bool result = false;
- if (getClient(socket) == NULL)
+ if (getClient(name) == NULL)
{
- ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
+ ClientInstance *instance = new ClientInstance(name, pid);
if (instance != NULL)
{
- mapClients.insert(make_pair(socket, instance));
+ mapClients.insert(make_pair(name, instance));
result = true;
}
else
{
- SCARD_DEBUG_ERR("alloc failed");
+ _ERR("alloc failed");
}
}
else
{
- SCARD_DEBUG_ERR("client already exist [%d]", socket);
+ _ERR("client already exist, name [%s]", name);
}
return result;
}
- ClientInstance *ServerResource::getClient(int socket)
+ ClientInstance *ServerResource::getClient(const char *name)
{
ClientInstance *result = NULL;
- map<int, ClientInstance *>::iterator item;
+ map<string, ClientInstance *>::iterator item;
- if ((item = mapClients.find(socket)) != mapClients.end())
+ if ((item = mapClients.find(name)) != 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);
- }
- }
-
- int ServerResource::getClientCount()
- {
- return (int)mapClients.size();
- }
-
- void ServerResource::removeClient(int socket)
+ void ServerResource::removeClient(const char *name)
{
- map<int, ClientInstance *>::iterator item;
+ map<string, ClientInstance *>::iterator item;
- if ((item = mapClients.find(socket)) != mapClients.end())
+ if ((item = mapClients.find(name)) != mapClients.end())
{
- ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
-
delete item->second;
mapClients.erase(item);
}
else
{
- SCARD_DEBUG("client removed already [%d]", socket);
+ _DBG("client removed already, name [%s]", name);
}
}
void ServerResource::removeClients()
{
- map<int, ClientInstance *>::iterator item;
+ map<string, 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();
}
- ServiceInstance *ServerResource::createService(int socket, unsigned int context)
+ int ServerResource::getClientCount() const
+ {
+ return (int)mapClients.size();
+ }
+
+ ServiceInstance *ServerResource::createService(const char *name)
{
ServiceInstance *result = NULL;
ClientInstance *instance = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((instance = getClient(name)) != NULL)
{
- if ((result = instance->getService(context)) == NULL)
+ if ((result = instance->createService()) == NULL)
{
- if ((result = instance->createService(context)) == NULL)
- {
- SCARD_DEBUG_ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
- }
+ _ERR("ClientInstance::createService failed [%d]", name);
}
}
else
{
- SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+ _ERR("client doesn't exist, name [%s]", name);
}
return result;
}
- ServiceInstance *ServerResource::getService(int socket, unsigned int context)
+ ServiceInstance *ServerResource::getService(const char *name, unsigned int handle)
{
ServiceInstance *result = NULL;
ClientInstance *instance = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((instance = getClient(name)) != NULL)
{
- result = instance->getService(context);
+ result = instance->getService(handle);
}
else
{
- SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+ _ERR("client doesn't exist, name [%s]", name);
}
return result;
}
- void ServerResource::removeService(int socket, unsigned int context)
+ void ServerResource::removeService(const char *name, unsigned int handle)
{
ClientInstance *instance = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((instance = getClient(name)) != NULL)
{
- instance->removeService(context);
+ instance->removeService(handle);
+ if (instance->getServiceCounts() == 0) {
+
+ /* remove client instance */
+ removeClient(name);
+ }
}
else
{
- SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+ _ERR("client doesn't exist, name [%s]", name);
}
}
- void ServerResource::removeServices(int socket)
+ void ServerResource::removeServices(const char *name)
{
ClientInstance *instance = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((instance = getClient(name)) != NULL)
{
instance->removeServices();
+
+ /* remove client instance */
+ removeClient(name);
}
else
{
- SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+ _ERR("client doesn't exist, name [%s]", name);
}
}
- Terminal *ServerResource::getTerminal(unsigned int terminalID)
+ unsigned int ServerResource::createSession(const char *name, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
{
- Terminal *result = NULL;
- map<unsigned int, Terminal *>::iterator item;
+ unsigned int result = -1;
+ Terminal *temp = NULL;
+ ServiceInstance *instance = NULL;
- if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
+ if ((instance = getService(name, handle)) != NULL)
{
- result = item->second;
+ if ((temp = getTerminalByReaderID(readerID)) != NULL)
+ {
+ result = instance->openSession(temp, certHashes, caller);
+ }
}
else
{
- SCARD_DEBUG_ERR("Terminal doesn't exist [%d]", terminalID);
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
}
return result;
}
- Terminal *ServerResource::getTerminal(const char *name)
+ ServerSession *ServerResource::getSession(const char *name, unsigned int handle, unsigned int sessionID)
{
- Terminal *result = NULL;
- map<unsigned int, Terminal *>::iterator item;
+ ServerSession *result = NULL;
+ ServiceInstance *instance = NULL;
- for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
+ if ((instance = getService(name, handle)) != NULL)
{
- if (strncmp(name, item->second->getName(), strlen(name)) == 0)
- {
- result = item->second;
- break;
- }
+ result = instance->getSession(sessionID);
+ }
+ else
+ {
+ _ERR("Session doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, sessionID);
}
return result;
}
- Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
+ bool ServerResource::isValidSessionHandle(const char *name, unsigned int handle, unsigned int session)
{
- Terminal *result = NULL;
- map<unsigned int, unsigned int>::iterator item;
+ ServiceInstance *instance = NULL;
- if ((item = mapReaders.find(readerID)) != mapReaders.end())
+ return (((instance = getService(name, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
+ }
+
+ bool ServerResource::isValidChannelHandle(const char *name, unsigned int handle, unsigned int channel)
+ {
+ ServiceInstance *instance = NULL;
+
+ return (((instance = getService(name, handle)) != NULL) && (instance->isVaildChannelHandle(channel)));
+ }
+
+ unsigned int ServerResource::getChannelCount(const char *name, unsigned int handle, unsigned int sessionID)
+ {
+ unsigned int result = -1;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
{
- result = getTerminal(item->second);
+ result = instance->getChannelCountBySession(sessionID);
}
else
{
- SCARD_DEBUG_ERR("Terminal doesn't exist, reader ID [%d]", readerID);
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
}
return result;
}
- unsigned int ServerResource::getTerminalID(const char *name)
+ void ServerResource::removeSession(const char *name, unsigned int handle, unsigned int sessionID)
{
- unsigned int result = IntegerHandle::INVALID_HANDLE;
- map<unsigned int, Terminal *>::iterator item;
+ ServiceInstance *instance = NULL;
- for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
+ if ((instance = getService(name, handle)) != NULL)
{
- if (strncmp(name, item->second->getName(), strlen(name)) == 0)
+ instance->closeSession(sessionID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+ }
+
+ unsigned int ServerResource::createChannel(const char *name, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
+ throw(ExceptionBase &)
+ {
+ unsigned int result = -1;
+ ServiceInstance *service = NULL;
+
+ if ((service = getService(name, handle)) != NULL)
+ {
+ if (service->isVaildSessionHandle(sessionID) == true)
{
- result = item->first;
- break;
+ ServerSession *session = NULL;
+ Terminal *terminal = NULL;
+
+ terminal = service->getTerminal(sessionID);
+ session = service->getSession(sessionID);
+ if (terminal != NULL && session != NULL)
+ {
+ if (terminal->open() == true) {
+ result = _createChannel(terminal, service, channelType, sessionID, aid);
+ if (result == IntegerHandle::INVALID_HANDLE)
+ {
+ _ERR("create channel failed [%d]", sessionID);
+
+ terminal->close();
+ }
+ } else {
+ _ERR("terminal open failed");
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
+ }
+ }
+ else
+ {
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
+ }
}
+ else
+ {
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
+ }
+ }
+ else
+ {
+ _ERR("getService is failed, name [%s], handle [%d]", name, handle);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
}
return result;
}
- unsigned int ServerResource::createSession(int socket, unsigned int context, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
+ Channel *ServerResource::getChannel(const char *name, unsigned int handle, unsigned int channelID)
{
- unsigned int result = -1;
- Terminal *temp = NULL;
+ Channel *result = NULL;
ServiceInstance *instance = NULL;
- if ((instance = getService(socket, context)) != NULL)
+ if ((instance = getService(name, handle)) != NULL)
{
- if ((temp = getTerminalByReaderID(readerID)) != NULL)
- {
- result = instance->openSession(temp, certHashes, caller);
- }
+ result = instance->getChannel(channelID);
}
else
{
- SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ _ERR("Channel doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, channelID);
}
return result;
}
- ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
+ void ServerResource::removeChannel(const char *name, unsigned int handle, unsigned int channelID)
{
- ServerSession *result = NULL;
ServiceInstance *instance = NULL;
- if ((instance = getService(socket, context)) != NULL)
+ if ((instance = getService(name, handle)) != NULL)
{
- result = instance->getSession(sessionID);
+ ServerChannel *channel;
+ Terminal *terminal = NULL;
+
+ channel = instance->getChannel(channelID);
+ if (channel != NULL) {
+ terminal = channel->getTerminal();
+ }
+
+ instance->closeChannel(channelID);
+
+ if (terminal != NULL) {
+ terminal->close();
+ }
}
else
{
- SCARD_DEBUG_ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+ }
+
+ 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
+ {
+ _ERR("Terminal doesn't exist [%d]", terminalID);
}
return result;
}
- unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
+ const Terminal *ServerResource::getTerminal(unsigned int terminalID) const
{
- unsigned int result = -1;
- ServiceInstance *instance = NULL;
+ const Terminal *result = NULL;
+ map<unsigned int, Terminal *>::const_iterator item;
- if ((instance = getService(socket, context)) != NULL)
+ if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
{
- result = instance->getChannelCountBySession(sessionID);
+ result = item->second;
}
else
{
- SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ _ERR("Terminal doesn't exist [%d]", terminalID);
}
return result;
}
- void ServerResource::removeSession(int socket, unsigned int context, unsigned int sessionID)
+ Terminal *ServerResource::getTerminal(const char *name)
{
- ServiceInstance *instance = NULL;
+ Terminal *result = NULL;
+ map<unsigned int, Terminal *>::iterator item;
- if ((instance = getService(socket, context)) != NULL)
+ for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
{
- instance->closeSession(sessionID);
+ if (strncmp(name, item->second->getName(), strlen(name)) == 0)
+ {
+ result = item->second;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
+ {
+ Terminal *result = NULL;
+ map<unsigned int, unsigned int>::iterator item;
+
+ if ((item = mapReaders.find(readerID)) != mapReaders.end())
+ {
+ result = getTerminal(item->second);
}
else
{
- SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
+ }
+
+ return result;
+ }
+
+ const Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID) const
+ {
+ const Terminal *result = NULL;
+ map<unsigned int, unsigned int>::const_iterator item;
+
+ if ((item = mapReaders.find(readerID)) != mapReaders.end())
+ {
+ result = getTerminal(item->second);
+ }
+ else
+ {
+ _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
+ }
+
+ return result;
+ }
+
+ unsigned int ServerResource::getTerminalID(const char *name) const
+ {
+ unsigned int result = IntegerHandle::INVALID_HANDLE;
+ map<unsigned int, Terminal *>::const_iterator item;
+
+ for (item = mapTerminals.begin();
+ item != mapTerminals.end(); item++)
+ {
+ if (strncmp(name, item->second->getName(),
+ strlen(name)) == 0)
+ {
+ result = item->first;
+ break;
+ }
}
+
+ return result;
}
- bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
+ bool ServerResource::_isAuthorizedAccess(ServerChannel *channel,
+ const ByteArray &aid, const vector<ByteArray> &hashes)
{
- bool result = true;
+ bool result = false;
AccessControlList *acList = NULL;
/* request open channel sequence */
- if ((acList = getAccessControlList(channel)) != NULL)
+ if ((acList = getAccessControlList(channel)) == NULL)
{
- PKCS15 pkcs15(channel);
+ /* load access control defined by Global Platform */
+ GPACE *acl = new GPACE();
+ if (acl != NULL)
+ {
+ int ret;
- acList->loadACL(channel);
- result = acList->isAuthorizedAccess(aid, hashes);
+ ret = acl->loadACL(channel);
+ if (ret >= SCARD_ERROR_OK)
+ {
+ acList = acl;
+ addAccessControlList(channel, acList);
+ }
+ else
+ {
+ _ERR("unknown error, 0x%x", -ret);
+ delete acl;
+ }
+ }
+ else
+ {
+ _ERR("alloc failed");
+ }
}
else
{
- SCARD_DEBUG_ERR("acList is null");
- result = false;
+ acList->loadACL(channel);
+ }
+
+ if (acList != NULL)
+ {
+ result = acList->isAuthorizedAccess(aid, hashes);
}
return result;
/* open channel */
command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
+
+ _DBG("command [%d] : %s", command.size(), command.toString().c_str());
+
rv = terminal->transmitSync(command, response);
- if (rv == 0 && response.getLength() >= 2)
+ if (rv == 0 && response.size() >= 2)
{
ResponseHelper resp(response);
- if (resp.getStatus() == 0)
+ if (resp.getStatus() >= 0)
{
result = resp.getDataField()[0];
}
else
{
- SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
- if (0)
- {
- /* TODO : if there is no more channel, return error code */
- SCARD_DEBUG_ERR("no more logical channel");
- result = -2;
- }
+ result = resp.getStatus();
}
}
else
{
- SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+ _ERR("transmitSync failed, rv [%d], length [%d]", rv, response.size());
}
return result;
int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
{
- int result = -1;
+ int result = SCARD_ERROR_UNKNOWN;
int rv = 0;
ByteArray command;
ByteArray response;
/* open channel */
command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
+
+ _DBG("command [%d] : %s", command.size(), command.toString().c_str());
+
rv = terminal->transmitSync(command, response);
- if (rv == 0 && response.getLength() >= 2)
+ if (rv == 0 && response.size() >= 2)
{
ResponseHelper resp(response);
- if (resp.getStatus() == 0)
+ if (resp.getStatus() >= 0)
{
- SCARD_DEBUG("channel closed [%d]", channelNum);
- result = 0;
+ _DBG("channel closed [%d]", channelNum);
+ result = SCARD_ERROR_OK;
}
else
{
- SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
+ _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
}
}
else
{
- SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+ _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.size());
}
return result;
}
- unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
+ unsigned int ServerResource::_createChannel(Terminal *terminal,
+ ServiceInstance *service, int channelType,
+ unsigned int sessionID, const ByteArray &aid)
throw(ExceptionBase &)
{
unsigned int result = IntegerHandle::INVALID_HANDLE;
channelNum = _openLogicalChannel(terminal);
if (channelNum > 0)
{
- SCARD_DEBUG("channelNum [%d]", channelNum);
+ _DBG("channelNum [%d]", channelNum);
}
else
{
- SCARD_DEBUG_ERR("_openLogicalChannel failed [%d]", channelNum);
+ _ERR("_openLogicalChannel failed [%d]", channelNum);
throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
}
}
result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
if (result == IntegerHandle::INVALID_HANDLE)
{
- SCARD_DEBUG_ERR("channel is null.");
+ _ERR("channel is null.");
/* close logical channel */
if (channelNum > 0)
channel = service->getChannel(result);
/* check */
- if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
- aid, service->getParent()->getCertificationHashes()) == true)
+ if (_isAuthorizedAccess(channel, aid,
+ service->getParent()->getCertificationHashes()) == true)
{
int rv = 0;
{
PKCS15 pkcs15(channel);
- if (pkcs15.isClosed() == false)
+ rv = pkcs15.select();
+ if (rv >= SCARD_ERROR_OK)
{
/* remove privilege mode */
channel->unsetPrivilegeMode();
+ channel->setSelectResponse(pkcs15.getSelectResponse());
}
else
{
- SCARD_DEBUG_ERR("select failed");
+ _ERR("select failed, [%x]", -rv);
service->closeChannel(result);
throw ExceptionBase(SCARD_ERROR_IO_FAILED);
FileObject file(channel);
rv = file.select(aid);
- if (rv == FileObject::SUCCESS)
+ if (rv >= SCARD_ERROR_OK)
{
/* remove privilege mode */
channel->unsetPrivilegeMode();
+ channel->setSelectResponse(file.getSelectResponse());
}
else
{
- SCARD_DEBUG_ERR("select failed [%d]", rv);
+ _ERR("select failed [%x]", -rv);
service->closeChannel(result);
throw ExceptionBase(SCARD_ERROR_IO_FAILED);
}
else
{
- SCARD_DEBUG_ERR("unauthorized access");
+ _ERR("unauthorized access");
service->closeChannel(result);
throw ExceptionBase(SCARD_ERROR_SECURITY_NOT_ALLOWED);
return result;
}
- unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
- throw(ExceptionBase &)
- {
- unsigned int result = -1;
- ServiceInstance *service = NULL;
-
- if ((service = getService(socket, context)) != NULL)
- {
- if (service->isVaildSessionHandle(sessionID) == true)
- {
- ServerSession *session = NULL;
- Terminal *terminal = NULL;
-
- terminal = service->getTerminal(sessionID);
- session = service->getSession(sessionID);
- if (terminal != NULL && session != NULL)
- {
- result = _createChannel(terminal, service, channelType, sessionID, aid);
- if (result == IntegerHandle::INVALID_HANDLE)
- {
- SCARD_DEBUG_ERR("create channel failed [%d]", sessionID);
- }
- }
- else
- {
- SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
- throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
- }
- }
- else
- {
- SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
- throw ExceptionBase(SCARD_ERROR_ILLEGAL_PARAM);
- }
- }
- else
- {
- SCARD_DEBUG_ERR("getService is failed [%d] [%d]", socket, context);
- throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
- }
-
- return result;
- }
-
- Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
+ void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
{
- Channel *result = NULL;
- ServiceInstance *instance = NULL;
+ map<Terminal *, AccessControlList *>::iterator item;
- if ((instance = getService(socket, context)) != NULL)
+ if ((item = mapACL.find(terminal)) == mapACL.end())
{
- result = instance->getChannel(channelID);
+ mapACL.insert(make_pair(terminal, acl));
}
else
{
- SCARD_DEBUG_ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
+ item->second = acl;
}
-
- return result;
}
- void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
+ void ServerResource::addAccessControlList(ServerChannel *channel, AccessControlList *acl)
{
- ServiceInstance *instance = NULL;
+ map<Terminal *, AccessControlList *>::iterator item;
- if ((instance = getService(socket, context)) != NULL)
+ if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
{
- instance->closeChannel(channelID);
+ mapACL.insert(make_pair(channel->getTerminal(), acl));
}
else
{
- SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ item->second = acl;
}
}
AccessControlList *result = NULL;
map<Terminal *, AccessControlList *>::iterator item;
- if ((item = mapACL.find(terminal)) == mapACL.end())
- {
- /* load access control */
- result = new GPSEACL();
- if (result != NULL)
- {
- mapACL.insert(make_pair(terminal, result));
- }
- else
- {
- SCARD_DEBUG_ERR("alloc failed");
- }
- }
- else
+ if ((item = mapACL.find(terminal)) != mapACL.end())
{
result = item->second;
}
AccessControlList *result = NULL;
map<Terminal *, AccessControlList *>::iterator item;
- if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
- {
- /* load access control */
- result = new GPSEACL();
- if (result != NULL)
- {
- mapACL.insert(make_pair(channel->getTerminal(), result));
- }
- else
- {
- SCARD_DEBUG_ERR("alloc failed");
- }
- }
- else
+ if ((item = mapACL.find(channel->getTerminal())) != mapACL.end())
{
result = item->second;
}
terminal = (Terminal *)createInstance();
if (terminal != NULL)
{
- SCARD_DEBUG("terminal [%p]", terminal);
+ _DBG("terminal [%p]", terminal);
}
else
{
- SCARD_DEBUG_ERR("terminal is null");
+ _ERR("terminal is null");
}
}
else
{
- SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
+ _ERR("create_instance is null [%d]", errno);
}
return terminal;
terminal->setStatusCallback(&ServerResource::terminalCallback);
- SCARD_DEBUG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
+ _DBG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
if (terminal->isSecureElementPresence() == true)
{
}
else
{
- SCARD_DEBUG_ERR("terminal is null [%s]", library);
+ _ERR("terminal is null [%s]", library);
dlclose(libHandle);
}
}
else
{
- SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
+ _ERR("it is not se file [%s] [%d]", library, errno);
}
return result;
strncmp(entry->d_name, "..", 2) != 0)
{
char fullPath[1024];
-
/* TODO : need additional name rule :) */
/* append each files */
snprintf(fullPath, sizeof(fullPath),
"%s/%s", OMAPI_SE_PATH, entry->d_name);
- SCARD_DEBUG("se name [%s]", fullPath);
+ SECURE_LOGD("se name [%s]", fullPath);
result = appendSELibrary(fullPath);
}
}
}
- bool ServerResource::isValidReaderHandle(unsigned int reader)
+ bool ServerResource::isValidReaderHandle(unsigned int reader) const
{
return (getTerminalByReaderID(reader) != NULL);
}
- bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
+ void ServerResource::getReaders(vector<pair<unsigned int, string> > &readers) const
{
- ServiceInstance *instance = NULL;
+ const Terminal *terminal;
+ map<unsigned int, unsigned int>::const_iterator item;
+
+ readers.clear();
- return (((instance = getService(socket, context)) != NULL) && (instance->isVaildSessionHandle(session)));
+ for (item = mapReaders.begin(); item != mapReaders.end(); item++)
+ {
+ if (item->second != IntegerHandle::INVALID_HANDLE)
+ {
+ terminal = getTerminal(item->second);
+ if (terminal != NULL && terminal->isSecureElementPresence() == true)
+ {
+ readers.push_back(make_pair(item->first, terminal->getName()));
+ }
+ }
+ }
}
- int ServerResource::getReadersInformation(ByteArray &info)
+ int ServerResource::getReadersInformation(ByteArray &info) const
{
int result = 0;
unsigned char *buffer = NULL;
if (mapReaders.size() > 0)
{
- Terminal *terminal = NULL;
- map<unsigned int, unsigned int>::iterator item;
+ const Terminal *terminal = NULL;
+ map<unsigned int, unsigned int>::const_iterator item;
for (item = mapReaders.begin(); item != mapReaders.end(); item++)
{
}
}
- info.setBuffer(buffer, length);
+ info.assign(buffer, length);
delete []buffer;
}
else
{
- SCARD_DEBUG_ERR("alloc failed");
+ _ERR("alloc failed");
result = -1;
}
}
else
{
- SCARD_DEBUG("no secure element");
+ _INFO("no secure element");
}
return result;
}
- bool ServerResource::sendMessageToAllClients(Message &msg)
+ void ServerResource::terminalCallback(const void *terminal, int event,
+ int error, void *user_param)
{
- 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_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
+ _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
switch (event)
{
{
ServerResource &instance = ServerResource::getInstance();
unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
- Message msg;
- SCARD_DEBUG("[NOTIFY_SE_AVAILABLE]");
+ _INFO("[NOTIFY_SE_AVAILABLE]");
terminalID = instance.getTerminalID((char *)terminal);
if (terminalID != IntegerHandle::INVALID_HANDLE)
{
- /* send all client to refresh reader */
- msg.message = msg.MSG_NOTIFY_SE_INSERTED;
- msg.param1 = instance.createReader(terminalID);
- msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+ unsigned int readerID = instance.createReader(terminalID);
- instance.sendMessageToAllClients(msg);
+ ServerGDBus::getInstance().emitReaderInserted(readerID, (const char *)terminal);
}
}
break;
{
ServerResource &instance = ServerResource::getInstance();
unsigned int readerID = IntegerHandle::INVALID_HANDLE;
- Message msg;
- SCARD_DEBUG("[NOTIFY_SE_NOT_AVAILABLE]");
+ _INFO("[NOTIFY_SE_NOT_AVAILABLE]");
readerID = instance.getReaderID((char *)terminal);
- /* send all client to refresh reader */
- msg.message = msg.MSG_NOTIFY_SE_REMOVED;
- msg.param1 = readerID;
- msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+ ServerGDBus::getInstance().emitReaderRemoved(
+ readerID, (const char *)terminal);
- instance.sendMessageToAllClients(msg);
instance.removeReader(readerID);
}
break;
default :
- SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
+ _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
break;
}
}
return result;
}
- unsigned int ServerResource::getReaderID(const char *name)
+ unsigned int ServerResource::getReaderID(const char *name) const
{
- unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
+ unsigned int result = IntegerHandle::INVALID_HANDLE,
+ terminalID = IntegerHandle::INVALID_HANDLE;
terminalID = getTerminalID(name);
if (terminalID != IntegerHandle::INVALID_HANDLE)
{
- map<unsigned int, unsigned int>::iterator item;
+ map<unsigned int, unsigned int>::const_iterator item;
- for (item = mapReaders.begin(); item != mapReaders.end(); item++)
+ for (item = mapReaders.begin();
+ item != mapReaders.end(); item++)
{
if (item->second == terminalID)
{
}
}
-} /* namespace smartcard_service_api */
+ ServerChannel *ServerResource::createInternalChannel(Terminal *terminal,
+ int channelType)
+ {
+ int channelNum = 0;
+ ServerChannel *channel = NULL;
-using namespace smartcard_service_api;
+ /* open logical channel */
+ if (channelType == 1)
+ {
+ channelNum = _openLogicalChannel(terminal);
+ if (channelNum > 0)
+ {
+ _DBG("channelNum [%d]", channelNum);
+ }
+ else
+ {
+ _ERR("_openLogicalChannel failed [%d]", channelNum);
+ throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
+ }
+ }
-EXTERN_API void server_resource_set_main_loop_instance(void *instance)
-{
- ServerResource::getInstance().setMainLoopInstance(instance);
-}
+ /* create channel instance */
+ channel = new ServerChannel(NULL, NULL, channelNum, terminal);
+
+ return channel;
+ }
+
+ bool ServerResource::isAuthorizedNFCAccess(Terminal *terminal,
+ const ByteArray &aid, const vector<ByteArray> &hashes)
+ {
+ bool result = false;
+ ServerChannel *channel;
+
+ if (terminal == NULL) {
+ return result;
+ }
+
+ channel = createInternalChannel(terminal, 1);
+ if (channel != NULL) {
+ AccessControlList *acl = getAccessControlList(channel);
+ if (acl == NULL) {
+
+ /* load access control defined by Global Platform */
+ acl = new GPACE();
+ if (acl != NULL) {
+ int ret;
+
+ ret = acl->loadACL(channel);
+ if (ret >= SCARD_ERROR_OK) {
+ addAccessControlList(channel, acl);
+ } else {
+ _ERR("unknown error, 0x%x", -ret);
+
+ delete acl;
+ acl = NULL;
+ }
+ } else {
+ _ERR("alloc failed");
+ }
+ } else {
+ acl->updateACL(channel);
+ }
+
+ if (acl != NULL) {
+ result = acl->isAuthorizedNFCAccess(aid, hashes);
+ } else {
+ _ERR("acl is null");
+ }
+
+ delete channel;
+ } else {
+ _ERR("alloc failed");
+ }
+
+ return result;
+ }
+
+ bool ServerResource::isAuthorizedAccess(Terminal *terminal,
+ const ByteArray &aid, const vector<ByteArray> &hashes)
+ {
+ bool result = false;
+ ServerChannel *channel;
+
+ if (terminal == NULL) {
+ return result;
+ }
+
+ channel = createInternalChannel(terminal, 1);
+ if (channel != NULL) {
+ AccessControlList *acl = getAccessControlList(channel);
+ if (acl == NULL) {
+
+ /* load access control defined by Global Platform */
+ acl = new GPACE();
+ if (acl != NULL) {
+ int ret;
+
+ ret = acl->loadACL(channel);
+ if (ret >= SCARD_ERROR_OK) {
+ addAccessControlList(channel, acl);
+ } else {
+ _ERR("unknown error, 0x%x", -ret);
+
+ delete acl;
+ acl = NULL;
+ }
+ } else {
+ _ERR("alloc failed");
+ }
+ } else {
+ acl->updateACL(channel);
+ }
+
+ if (acl != NULL) {
+ result = acl->isAuthorizedAccess(aid, hashes);
+ } else {
+ _ERR("acl is null");
+ }
+
+ delete channel;
+ } else {
+ _ERR("alloc failed");
+ }
+
+ return result;
+ }
+
+ void ServerResource::finish()
+ {
+ if (getClientCount() == 0) {
+ _INFO("no client connected. terminate server");
+
+ smartcard_daemon_exit();
+ }
+ }
+} /* namespace smartcard_service_api */
/* local header */
#include "Debug.h"
-#include "Message.h"
#include "TerminalInterface.h"
-#include "ServerSEService.h"
#include "ServerResource.h"
+#include "ServerSEService.h"
namespace smartcard_service_api
{
terminal = (Terminal *)createInstance();
if (terminal != NULL)
{
- SCARD_DEBUG("terminal [%p]", terminal);
+ _DBG("terminal [%p]", terminal);
}
else
{
- SCARD_DEBUG_ERR("terminal is null");
+ _ERR("terminal is null");
}
}
else
{
- SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
+ _ERR("create_instance is null [%d]", errno);
}
return terminal;
terminal = createInstance(libHandle);
if (terminal != NULL)
{
- SCARD_DEBUG("SE info : [%s] [%s]", library, terminal->getName());
+ _DBG("SE info : [%s] [%s]", library, terminal->getName());
libraries.push_back(libHandle);
- pair<char *, Terminal *> newPair(terminal->getName(), terminal);
+ pair<string, 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());
+ _DBG("register success [%s]", terminal->getName());
readers.push_back(reader);
}
else
{
- SCARD_DEBUG_ERR("ServerReader alloc failed [%s]", terminal->getName());
+ _ERR("ServerReader alloc failed [%s]", terminal->getName());
/* throw exception */
}
}
else
{
- SCARD_DEBUG("SE is not ready [%s]", terminal->getName());
+ _DBG("SE is not ready [%s]", terminal->getName());
}
result = true;
}
else
{
- SCARD_DEBUG_ERR("createInstance failed [%s]", library);
+ _ERR("createInstance failed [%s]", library);
dlclose(libHandle);
}
}
else
{
- SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
+ _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;
/* 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);
+ SECURE_LOGD("se name [%s]", fullPath);
result = appendSELibrary(fullPath);
}
}
}
- bool ServerSEService::dispatcherCallback(void *message, int socket)
+#if 0
+ bool ServerSEService::isValidReaderHandle(void *handle)
{
- int count;
- ByteArray info;
- Message *msg = (Message *)message;
- Message response(*msg);
- ServerResource &resource = ServerResource::getInstance();
+ bool result = false;
+ size_t i;
- if (resource.createService(socket, msg->error) != NULL)
+ for (i = 0; i < readers.size(); i++)
{
- SCARD_DEBUG_ERR("client added : pid [%d]", msg->error);
-
- response.error = SCARD_ERROR_OK;
-
- if ((count = resource.getReadersInformation(info)) > 0)
+ if ((void *)readers[i] == handle)
{
- response.param1 = count;
- response.data = info;
+ result = true;
+ break;
}
- else
- {
- SCARD_DEBUG("no secure elements");
- response.param1 = 0;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("createClient failed");
-
- response.error = SCARD_ERROR_OUT_OF_MEMORY;
}
- /* response to client */
- ServerIPC::getInstance()->sendMessage(socket, &response);
-
return false;
}
+#endif
- void ServerSEService::terminalCallback(void *terminal, int event, int error, void *user_param)
+ void ServerSEService::terminalCallback(const void *terminal, int event, int error, void *user_param)
{
- Message msg;
-// Terminal *term = NULL;
-
switch (event)
{
case Terminal::NOTIFY_SE_AVAILABLE :
- /* 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);
+ {
+ /* add right se reader */
+// if ((term = ServerResource::getInstance().getTerminal((char *)terminal)) != NULL)
+// {
+// _DBG("terminal : [%s]", (char *)terminal);
+//
+// term->initialize();
+// }
+// else
+// {
+// _DBG("unknown terminal : [%s]", (char *)terminal);
+// }
+ }
break;
case Terminal::NOTIFY_SE_NOT_AVAILABLE :
- /* 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);
+ {
+ /* remove right se reader */
+// if ((term = ServerResource::getInstance().getTerminal((char *)terminal)) != NULL)
+// {
+// _DBG("terminal : [%s]", (char *)terminal);
+//
+// term->finalize();
+// }
+// else
+// {
+// _DBG("unknown terminal : [%s]", (char *)terminal);
+// }
+ }
break;
default :
#include "ServerReader.h"
#include "ServerChannel.h"
#include "APDUHelper.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
namespace smartcard_service_api
{
- ServerSession::ServerSession(ServerReader *reader, vector<ByteArray> &certHashes, void *caller, Terminal *terminal):SessionHelper(reader)
+ ServerSession::ServerSession(ServerReader *reader,
+ const vector<ByteArray> &certHashes,
+ void *caller, Terminal *terminal) : SessionHelper(reader)
{
- this->caller = NULL;
this->terminal = NULL;
- if (caller == NULL || terminal == NULL)
+ if (terminal == NULL)
{
- SCARD_DEBUG_ERR("invalid param");
+ _ERR("invalid param");
return;
}
- this->caller = caller;
this->terminal = terminal;
this->certHashes = certHashes;
}
closeSync();
}
- ByteArray ServerSession::getATRSync()
+ const ByteArray ServerSession::getATRSync()
throw(ErrorIO &, ErrorIllegalState &)
{
/* call get atr to terminal */
+ if (atr.isEmpty()) {
+ if (terminal != NULL) {
+ if (terminal->open() == true) {
+ int error = terminal->getATRSync(atr);
+
+ if (error < SCARD_ERROR_OK) {
+ _ERR("getATRSync failed, [%d]", error);
+ }
+
+ terminal->close();
+ } else {
+ _ERR("terminal->open failed");
+ }
+ } else {
+ _ERR("terminal is null.");
+ }
+ }
+
return atr;
}
channels.clear();
}
- Channel *ServerSession::openBasicChannelSync(ByteArray aid)
+ Channel *ServerSession::openBasicChannelSync(const ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openBasicChannelSync(aid, NULL);
+ return openBasicChannelSync(aid, (void *)NULL);
}
- Channel *ServerSession::openBasicChannelSync(ByteArray aid, void *caller)
+ Channel *ServerSession::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
+ throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ return openBasicChannelSync(aid, (void *)NULL);
+ }
+
+ Channel *ServerSession::openBasicChannelSync(const ByteArray &aid, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
ServerChannel *channel = NULL;
+#if 0
+ AccessControlList *acList = NULL;
+ ByteArray command, result;
+ int channelID = 0;
+ int rv = 0;
+
+ _BEGIN();
+
+ acList = ((ServerReader *)reader)->getAccessControlList();
+ if (acList == NULL)
+ {
+ _ERR("acList is null");
+
+ return channel;
+ }
+
+ if (acList->isAuthorizedAccess(aid, certHashes) == false)
+ {
+ _ERR("unauthorized access, aid : %s", aid.toString().c_str());
+
+ return channel;
+ }
+
+ /* select aid */
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelID, aid);
+ rv = terminal->transmitSync(command, result);
+ if (rv == 0 && result.size() >= 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
+ {
+ _ERR("alloc failed");
+ }
+ }
+ else
+ {
+ _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
+ }
+ }
+ else
+ {
+ _ERR("select apdu is failed, rv [%d], length [%d]", rv, result.size());
+ }
+#endif
return channel;
}
- Channel *ServerSession::openBasicChannelSync(unsigned char *aid, unsigned int length)
+ Channel *ServerSession::openBasicChannelSync(const unsigned char *aid, unsigned int length)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openBasicChannelSync(ByteArray(aid, length));
+ unsigned char P2 = 0x00;
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp, P2);
+ }
+
+ Channel *ServerSession::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp, P2);
+ }
+
+ Channel *ServerSession::openBasicChannelSync(const unsigned char *aid, unsigned int length, void *caller)
+ throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp, caller);
}
- Channel *ServerSession::openBasicChannelSync(unsigned char *aid, unsigned int length, void *caller)
+ Channel *ServerSession::openLogicalChannelSync(const ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openBasicChannelSync(ByteArray(aid, length), caller);
+ void* caller;
+ return openLogicalChannelSync(aid, caller);
}
- Channel *ServerSession::openLogicalChannelSync(ByteArray aid)
+ Channel *ServerSession::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openLogicalChannelSync(aid, NULL);
+ void* caller;
+ return openLogicalChannelSync(aid, caller);
}
- Channel *ServerSession::openLogicalChannelSync(ByteArray aid, void *caller)
+ Channel *ServerSession::openLogicalChannelSync(const ByteArray &aid, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
ServerChannel *channel = NULL;
+#if 0
+ AccessControlList *acList = NULL;
+ ByteArray command, result;
+ int channelID = 1;
+ int rv;
+
+ acList = ((ServerReader *)reader)->getAccessControlList();
+ if (acList == NULL)
+ {
+ _ERR("unauthorized access, aid %s, hash %s");
+
+ return channel;
+ }
+
+ if (acList->isAuthorizedAccess(aid, certHashes) == false)
+ {
+ _ERR("unauthorized access, aid : %s", aid.toString().c_str());
+
+ return channel;
+ }
+
+ /* open channel */
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
+ rv = terminal->transmitSync(command, result);
+
+ if (rv == 0 && result.size() >= 2)
+ {
+ ResponseHelper resp(result);
+
+ if (resp.getStatus() == 0)
+ {
+ channelID = resp.getDataField()[0];
+ }
+ else
+ {
+ _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
+
+ return channel;
+ }
+ }
+ else
+ {
+ _ERR("select apdu is failed, rv [%d], length [%d]", rv, result.size());
+
+ return channel;
+ }
+
+ /* select aid */
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelID, aid);
+ rv = terminal->transmitSync(command, result);
+
+ if (rv == 0 && result.size() >= 2)
+ {
+ ResponseHelper resp(result);
+
+ if (resp.getStatus() == 0)
+ {
+ channel = new ServerChannel(this, caller, channelID, terminal);
+ if (channel == NULL)
+ {
+ _ERR("alloc failed");
+
+ return NULL;
+ }
+
+ channel->selectResponse = result;
+
+ channels.push_back(channel);
+ }
+ else
+ {
+ _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
+ }
+ }
+ else
+ {
+ _ERR("select apdu is failed, rv [%d], length [%d]", rv, result.size());
+ }
+#endif
return channel;
}
- Channel *ServerSession::openLogicalChannelSync(unsigned char *aid, unsigned int length)
+ Channel *ServerSession::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
+ throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ unsigned char P2 = 0x00;
+ ByteArray temp(aid, length);
+
+ return openLogicalChannelSync(temp, P2);
+ }
+
+ Channel *ServerSession::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openLogicalChannelSync(ByteArray(aid, length), NULL);
+ ByteArray temp(aid, length);
+
+ return openLogicalChannelSync(temp, P2);
}
- Channel *ServerSession::openLogicalChannelSync(unsigned char *aid, unsigned int length, void *caller)
+ Channel *ServerSession::openLogicalChannelSync(const unsigned char *aid, unsigned int length, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openLogicalChannelSync(ByteArray(aid, length), caller);
+ ByteArray temp(aid, length);
+
+ return openLogicalChannelSync(temp, caller);
}
} /* namespace smartcard_service_api */
namespace smartcard_service_api
{
- unsigned int ServiceInstance::openSession(Terminal *terminal, vector<ByteArray> &certHashes, void *caller)
+ ServiceInstance::ServiceInstance(ClientInstance *parent) :
+ parent(parent)
+ {
+ handle = IntegerHandle::assignHandle();
+ }
+
+ ServiceInstance::~ServiceInstance()
+ {
+ closeSessions();
+
+ if (handle != IntegerHandle::INVALID_HANDLE) {
+ IntegerHandle::releaseHandle(handle);
+ handle = IntegerHandle::INVALID_HANDLE;
+ }
+ }
+
+ unsigned int ServiceInstance::openSession(Terminal *terminal, const vector<ByteArray> &certHashes, void *caller)
{
unsigned int handle = IntegerHandle::assignHandle();
mapSessions.clear();
}
- unsigned int ServiceInstance::openChannel(unsigned int session, int channelNum, ByteArray response)
+ unsigned int ServiceInstance::openChannel(unsigned int session, int channelNum, const ByteArray &response)
{
Terminal *terminal = getTerminal(session);
ServerChannel *channel = NULL;
}
else
{
- SCARD_DEBUG_ERR("alloc failed");
+ _ERR("alloc failed");
}
return handle;
/* standard library header */
#include <map>
#include <vector>
-#include <glib.h>
+#include <string>
/* 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;
+ private :
+ string name;
+ pid_t pid;
vector<ByteArray> certHashes;
map<unsigned int, ServiceInstance *> mapServices;
- static gboolean _getCertificationHashes(gpointer user_data);
-
- public:
- ClientInstance(void *ioChannel, int socket, int watchID, int state, int pid)
+ public :
+ ClientInstance(const char *name, pid_t pid) :
+ name(name), pid(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; }
+ inline ~ClientInstance() { removeServices(); }
+ inline bool operator ==(const char *name) const { return (this->name.compare(name) == 0); }
- void setPID(int pid);
- inline int getPID() { return pid; }
+ inline void setPID(int pid) { this->pid = pid; }
+ inline int getPID() const { return pid; }
- ServiceInstance *createService(unsigned int context);
- ServiceInstance *getService(unsigned int context);
- void removeService(unsigned int context);
+ ServiceInstance *createService();
+ ServiceInstance *getService(unsigned int handle);
+ void removeService(unsigned int handle);
void removeServices();
-
- bool sendMessageToAllServices(int socket, Message &msg);
+ inline size_t getServiceCounts() const { return mapServices.size(); }
void generateCertificationHashes();
inline vector<ByteArray> &getCertificationHashes() { return certHashes; }
-
- friend gboolean _getCertificationHashes(gpointer user_data);
};
} /* namespace smartcard_service_api */
+
#endif /* CLIENTINSTANCE_H_ */
protected:
void closeSync()
throw(ErrorIO &, ErrorIllegalState &);
- int transmitSync(ByteArray command, ByteArray &result)
+ int transmitSync(const ByteArray &command, ByteArray &result)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
public:
int getChannelNumber() { return channelNum; }
Terminal *getTerminal() { return terminal; }
- int close(closeCallback callback, void *userParam) { return -1; }
- int transmit(ByteArray command, transmitCallback callback, void *userParam) { return -1; };
+ int close(closeChannelCallback callback, void *userParam) { return -1; }
+ int transmit(const ByteArray &command, transmitCallback callback, void *userParam) { return -1; };
friend class ServerReader;
friend class ServerSession;
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SERVERGDBUS_H_
+#define SERVERGDBUS_H_
+
+/* standard library header */
+#include <glib.h>
+#include <queue>
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "GDBusHelper.h"
+#include "smartcard-service-gdbus.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ typedef void (*dispatcher_cb_t)(vector<void *> ¶ms);
+
+ class GDBusDispatcher : public Synchronous
+ {
+ public :
+ static GDBusDispatcher &getInstance();
+
+ /* push to queue */
+ static void push(dispatcher_cb_t cb, const vector<void *> ¶ms);
+
+ private :
+ std::queue<pair<dispatcher_cb_t, vector<void *> > > q;
+
+ GDBusDispatcher();
+ ~GDBusDispatcher();
+
+ void _push(dispatcher_cb_t cb, const vector<void *> ¶ms);
+ static gboolean dispatch(gpointer user_data);
+ };
+
+ class ServerGDBus
+ {
+ public :
+ GDBusProxy *dbus_proxy;
+
+ static ServerGDBus &getInstance();
+
+ bool init();
+ void deinit();
+
+ /* connect to dbus daemon */
+ bool _init();
+ void _deinit();
+ pid_t getPID(const char *name);
+
+ void emitReaderInserted(unsigned int reader_id,
+ const char *reader_name);
+ void emitReaderRemoved(unsigned int reader_id,
+ const char *reader_name);
+
+ private :
+ GDBusConnection *connection;
+
+ SmartcardServiceSeService *seService;
+ SmartcardServiceReader *reader;
+ SmartcardServiceSession *session;
+ SmartcardServiceChannel *channel;
+
+ ServerGDBus();
+ ~ServerGDBus();
+
+ bool initSEService();
+ void deinitSEService();
+
+ bool initReader();
+ void deinitReader();
+
+ bool initSession();
+ void deinitSession();
+
+ bool initChannel();
+ void deinitChannel();
+ };
+} /* namespace smartcard_service_api */
+
+#endif /* SERVERGDBUS_H_ */
{
private:
Terminal *terminal;
- ServerChannel *adminChannel;
- AccessControlList *acList;
- ServerReader(ServerSEService *seService, char *name, Terminal *terminal);
+ ServerReader(ServerSEService *seService, const char *name, Terminal *terminal);
~ServerReader();
int openSession(openSessionCallback callback, void *userData) { return -1; }
void closeSessions()
throw(ErrorIO &, ErrorIllegalState &);
- AccessControlList *getAccessControlList();
-
ServerSession *openSessionSync()
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- ServerSession *openSessionSync(vector<ByteArray> &certHashes, void *caller)
+ ServerSession *openSessionSync(const vector<ByteArray> &certHashes, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
friend class ServerSEService;
#define SERVERRESOURCE_H_
/* standard library header */
-#ifdef __cplusplus
#include <map>
#include <vector>
#include <set>
-#endif /* __cplusplus */
+#include <string>
/* SLP library header */
/* local header */
-#ifdef __cplusplus
#include "Exception.h"
#include "Terminal.h"
#include "Lock.h"
-#include "ServerIPC.h"
-#include "ServerDispatcher.h"
#include "ServerReader.h"
#include "ServerSession.h"
#include "ClientInstance.h"
#include "ServiceInstance.h"
-#endif /* __cplusplus */
-#ifdef __cplusplus
using namespace std;
namespace smartcard_service_api
vector<void *> libraries;
map<unsigned int, Terminal *> mapTerminals; /* terminal unique id <-> terminal instance map */
map<unsigned int, unsigned int> mapReaders; /* reader unique id <-> terminal unique id map */
- map<int, ClientInstance *> mapClients; /* client pid <-> client instance map */
+ map<string, ClientInstance *> mapClients; /* client pid <-> client instance map */
map<Terminal *, AccessControlList *> mapACL; /* terminal instance <-> access control instance map */
- void *mainLoop;
- ServerIPC *serverIPC;
- ServerDispatcher *serverDispatcher;
bool seLoaded;
ServerResource();
bool appendSELibrary(char *library);
void clearSELibraries();
- static void terminalCallback(void *terminal, int event, int error, void *user_param);
+ static void terminalCallback(const void *terminal, int event, int error, void *user_param);
int _openLogicalChannel(Terminal *terminal);
int _closeLogicalChannel(Terminal *terminal, int channelNum);
- bool _isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes);
- unsigned int _createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
+ bool _isAuthorizedAccess(ServerChannel *channel, const ByteArray &aid, const vector<ByteArray> &hashes);
+ unsigned int _createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, const ByteArray &aid)
throw(ExceptionBase &);
+
public:
/* static member */
static ServerResource &getInstance();
- /* non-static member */
- inline void setMainLoopInstance(void *mainLoop)
- {
- this->mainLoop = mainLoop;
- }
- inline void *getMainLoopInstance()
- {
- return this->mainLoop;
- }
-
int loadSecureElements();
void unloadSecureElements();
Terminal *getTerminal(unsigned int terminalID);
+ const Terminal *getTerminal(unsigned int terminalID) const;
Terminal *getTerminal(const char *name);
Terminal *getTerminalByReaderID(unsigned int readerID);
- unsigned int getTerminalID(const char *name);
- int getReadersInformation(ByteArray &info);
- bool isValidReaderHandle(unsigned int reader);
+ const Terminal *getTerminalByReaderID(unsigned int readerID) const;
+ unsigned int getTerminalID(const char *name) const;
+ int getReadersInformation(ByteArray &info) const;
+ void getReaders(vector<pair<unsigned int, string> > &readers) const;
+ bool isValidReaderHandle(unsigned int reader) const;
unsigned int createReader(unsigned int terminalID);
- unsigned int getReaderID(const char *name);
+ unsigned int getReaderID(const char *name) const;
void removeReader(unsigned int readerID);
- bool createClient(void *ioChannel, int socket, int watchID, int state, int pid);
- ClientInstance *getClient(int socket);
- void setPID(int socket, int pid);
- int getClientCount();
- void removeClient(int socket);
+ bool createClient(const char *name, pid_t pid);
+ ClientInstance *getClient(const char *name);
+ void removeClient(const char *name);
void removeClients();
+ int getClientCount() const;
- ServiceInstance *createService(int socket, unsigned int context);
- ServiceInstance *getService(int socket, unsigned int context);
- void removeService(int socket, unsigned int context);
- void removeServices(int socket);
+ ServiceInstance *createService(const char *name);
+ ServiceInstance *getService(const char *name, unsigned int handle);
+ void removeService(const char *name, unsigned int handle);
+ void removeServices(const char *name);
- unsigned int createSession(int socket, unsigned int context, unsigned int readerID, vector<ByteArray> &certHashes, 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 createSession(const char *name, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller);
+ ServerSession *getSession(const char *name, unsigned int handle, unsigned int sessionID);
+ unsigned int getChannelCount(const char *name, unsigned int handle, unsigned int sessionID);
+ void removeSession(const char *name, unsigned int handle, unsigned int session);
+ bool isValidSessionHandle(const char *name, unsigned int handle, unsigned int sessionID);
+ bool isValidChannelHandle(const char *name, unsigned int handle, unsigned int channelID);
- unsigned int createChannel(int socket, unsigned int context,
+ unsigned int createChannel(const char *name, unsigned int handle,
unsigned int sessionID, int channelType, ByteArray aid)
throw(ExceptionBase &);
- Channel *getChannel(int socket, unsigned int context, unsigned int channelID);
- void removeChannel(int socket, unsigned int context, unsigned int channelID);
-
+ Channel *getChannel(const char *name, unsigned int handle, unsigned int channelID);
+ void removeChannel(const char *name, unsigned int handle, unsigned int channelID);
+ void addAccessControlList(Terminal *terminal, AccessControlList *acl);
+ void addAccessControlList(ServerChannel *channel, AccessControlList *acl);
AccessControlList *getAccessControlList(Terminal *terminal);
AccessControlList *getAccessControlList(ServerChannel *channel);
+ bool isAuthorizedNFCAccess(Terminal *terminal, const ByteArray &aid,
+ const vector<ByteArray> &hashes);
+ bool isAuthorizedAccess(Terminal *terminal,
+ const ByteArray &aid, const vector<ByteArray> &hashes);
+
+ void finish();
- bool sendMessageToAllClients(Message &msg);
+ /* FIXME ??? */
+ ServerChannel *createInternalChannel(Terminal *terminal,
+ int channelType);
friend void terminalCallback(void *terminal, int event, int error, void *user_param);
};
} /* namespace smartcard_service_api */
-#endif /* __cplusplus */
-
-/* export C API */
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-void server_resource_set_main_loop_instance(void *instance);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
#endif /* SERVERRESOURCE_H_ */
{
private:
vector<void *> libraries;
- map<char *, Terminal *> mapTerminals;
+ map<string, Terminal *> mapTerminals;
ServerSEService();
~ServerSEService();
int openSELibraries();
void closeSELibraries();
- static void terminalCallback(void *terminal, int event, int error, void *user_param);
+ static void terminalCallback(const 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
+
void shutdown() {}
void shutdownSync() {}
- friend void terminalCallback(char *name, int event, int error, void *user_param);
+
+ friend void terminalCallback(const void *name, int event, int error, void *user_param);
friend bool dispatcherCallback(void *message, int socket);
friend class ServerDispatcher;
};
class ServerSession : public SessionHelper
{
private:
- void *caller;
Terminal *terminal;
vector<ByteArray> certHashes;
- ServerSession(ServerReader *reader, vector<ByteArray> &certHashes, void *caller, Terminal *terminal);
+ ServerSession(ServerReader *reader,
+ const vector<ByteArray> &certHashes,
+ void *caller, Terminal *terminal);
- int getATR(getATRCallback callback, void *userData){ return -1; }
- int close(closeSessionCallback callback, void *userData){ return -1; }
+ 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; }
+ int openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData){ return -1; }
+ int openBasicChannel(const unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData){ return -1; }
+ int openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData){ return -1; }
+ int openLogicalChannel(const unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData){ return -1; }
public:
~ServerSession();
- ByteArray getATRSync()
+ const ByteArray getATRSync()
throw(ErrorIO &, ErrorIllegalState &);
void closeSync()
throw(ErrorIO &, ErrorIllegalState &);
void closeChannels()
throw(ErrorIO &, ErrorIllegalState &);
- Channel *openBasicChannelSync(ByteArray aid)
+ Channel *openBasicChannelSync(const ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openBasicChannelSync(unsigned char *aid, unsigned int length)
+ Channel *openBasicChannelSync(const unsigned char *aid, unsigned int length)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openBasicChannelSync(ByteArray aid, void *caller)
+ Channel *openBasicChannelSync(const ByteArray &aid, unsigned char P2)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openBasicChannelSync(unsigned char *aid, unsigned int length, void *caller)
+ Channel *openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
+ Channel *openBasicChannelSync(const ByteArray &aid, void *caller)
+ throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
+ Channel *openBasicChannelSync(const unsigned char *aid, unsigned int length, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openLogicalChannelSync(ByteArray aid)
+ Channel *openLogicalChannelSync(const ByteArray &aid)
+ throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
+ Channel *openLogicalChannelSync(const unsigned char *aid, unsigned int length)
+ throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
+ Channel *openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length)
+ Channel *openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openLogicalChannelSync(ByteArray aid, void *caller)
+ Channel *openLogicalChannelSync(const ByteArray &aid, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length, void *caller)
+ Channel *openLogicalChannelSync(const unsigned char *aid, unsigned int length, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
friend class ServerReader;
class ServiceInstance
{
private:
- unsigned int context;
+ unsigned int handle;
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(); };
+ ServiceInstance(ClientInstance *parent);
+ ~ServiceInstance();
- inline bool operator ==(const unsigned int &context) const { return (this->context == context); }
+ inline unsigned int getHandle() { return handle; }
+
+ inline bool operator ==(const unsigned int &handle) const { return (this->handle == handle); }
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, vector<ByteArray> &certHashes, void *caller);
+ unsigned int openSession(Terminal *terminal, const vector<ByteArray> &certHashes, 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, ByteArray response = ByteArray::EMPTY);
+ unsigned int openChannel(unsigned int session, int channelNum, const ByteArray &response = ByteArray::EMPTY);
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();
/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-/* standard library header */
+#ifndef SMARTCARD_DAEMON_H_
+#define SMARTCARD_DAEMON_H_
-/* SLP library header */
+void smartcard_daemon_exit();
-/* local header */
-#include "ReaderHelper.h"
-
-namespace smartcard_service_api
-{
- SessionHelper::SessionHelper(ReaderHelper *reader) :
- closed(true)
- {
- this->reader = reader;
- }
-} /* namespace smartcard_service_api */
+#endif /* SMARTCARD_DAEMON_H_ */
[D-BUS Service]
-Name=org.tizen.smartcard_service
-Exec=/usr/bin/smartcard-daemon
-User=root
\ No newline at end of file
+Name=org.tizen.SmartcardService
+Exec=/usr/apps/smartcard-service-server/bin/smartcard-daemon
+MemoryLimit=10M
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* standard library header */
+#include <glib.h>
+#include <gio/gio.h>
+#include <map>
+
+/* SLP library header */
+#ifdef USER_SPACE_SMACK
+#include "security-server.h"
+#endif
+
+/* local header */
+#include "Debug.h"
+#include "APDUHelper.h"
+#include "ServerResource.h"
+#include "SignatureHelper.h"
+#include "ServerGDBus.h"
+#include "PKCS15CDFACL.h"
+#include "access-control-gdbus.h"
+
+using namespace std;
+using namespace smartcard_service_api;
+
+static SmartcardServiceAccessControl *access_control;
+static map<string, ByteArray> mapGranted;
+static PKCS15CDFACL cdfAcl;
+
+static void _load_granted_package_info()
+{
+ mapGranted.clear();
+
+ /* TODO : load information form file */
+ mapGranted.insert(make_pair("nfc-manager", ByteArray::EMPTY));
+}
+
+static gboolean _compare_hash(char *package, ByteArray &hash)
+{
+ gboolean result = false;
+ vector<ByteArray> hashes;
+
+ /* get certificate hashes by pid */
+ if (SignatureHelper::getCertificationHashes(package, hashes) == true) {
+ vector<ByteArray>::iterator item;
+
+ for (item = hashes.begin(); item != hashes.end(); item++) {
+ if (*item == hash) {
+ result = true;
+ break;
+ }
+ }
+ } else {
+ _ERR("getCertificationHashes failed, [%s]", package);
+ }
+
+ return result;
+}
+
+static gboolean _check_permission(pid_t pid)
+{
+ gboolean result = false;
+ char package[1024];
+
+ if (SignatureHelper::getPackageName(pid,
+ package, sizeof(package)) == 0) {
+ map<string, ByteArray>::iterator item;
+
+ item = mapGranted.find(package);
+ if (item != mapGranted.end()) {
+ /* TODO : check privilege */
+ if (false) {
+ result = _compare_hash(package, item->second);
+ } else {
+ result = true;
+ }
+ }
+ } else {
+ _ERR("aul_app_get_pkgname_bypid failed");
+ }
+
+ return result;
+}
+
+static bool _get_se_name(unsigned int se_type, char *buf, size_t len)
+{
+ bool result = false;
+
+ switch ((se_type >> 4) & 0x0F) {
+ case 1 :
+ snprintf(buf, len, "SIM%d", (se_type & 0x0F) + 1);
+ result = true;
+ break;
+
+ case 2 :
+ snprintf(buf, len, "eSE");
+ result = true;
+ break;
+
+ default :
+ break;
+ }
+
+ return result;
+}
+
+static bool _is_authorized_request(GDBusMethodInvocation *invocation,
+ const char *rights)
+{
+ bool result = true;
+#ifdef USER_SPACE_SMACK
+ pid_t pid;
+ const char *name;
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ pid = ServerGDBus::getInstance().getPID(name);
+
+ result = (security_server_check_privilege_by_pid(
+ pid,
+ "smartcard-service::priv",
+ rights) == SECURITY_SERVER_API_SUCCESS);
+#endif
+ return result;
+}
+
+static gboolean __process_is_authorized_nfc_access(
+ SmartcardServiceAccessControl *object,
+ GDBusMethodInvocation *invocation,
+ guint se_type,
+ const gchar *package,
+ GVariant *aid,
+ void *user_data)
+{
+ bool result = false;
+ const char *error;
+ const char *name;
+ char se[10];
+ pid_t pid;
+
+ ByteArray temp;
+ Terminal *terminal;
+ vector<ByteArray> hashes;
+
+ _INFO("[MSG_IS_AUTHORIZED_NFC_ACCESS]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ pid = ServerGDBus::getInstance().getPID(name);
+
+ _INFO("service requested, pid [%d]", pid);
+
+ if (pid < 0) {
+ error = "invalid pid";
+
+ _ERR("%s, [%d]", error, pid);
+
+ goto ERR;
+ }
+
+ /* check process permission */
+ if (_check_permission(pid) == false) {
+ error = "permission denied";
+
+ _ERR("%s, [%d]", error, pid);
+
+ goto ERR;
+ }
+
+ /* load secure elements */
+ resource.loadSecureElements();
+
+ if (_get_se_name(se_type, se, sizeof(se)) == false) {
+ error = "unknown SE type";
+
+ _ERR("%s, [%d]", error, se_type);
+
+ goto ERR;
+ }
+
+ _INFO("SE : [%s]", se);
+
+ terminal = resource.getTerminal(se);
+ if (terminal == NULL) {
+ error = "failed getting terminal";
+
+ _ERR("%s, [%d]", error, se_type);
+
+ goto ERR;
+ }
+
+ if (terminal->isSecureElementPresence() == false) {
+ error = "terminal is not available now";
+
+ _ERR("%s, [%d]", error, se_type);
+
+ goto ERR;
+ }
+
+ /* get certificate hashes */
+ if (SignatureHelper::getCertificationHashes(package, hashes) == false) {
+ error = "failed getting certificates";
+
+ _ERR("%s, [%s]", error, package);
+
+ goto ERR;
+ }
+
+ /* convert AID */
+ GDBusHelper::convertVariantToByteArray(aid, temp);
+
+ result = resource.isAuthorizedNFCAccess(terminal, temp, hashes);
+
+ /* response to client */
+ smartcard_service_access_control_complete_is_authorized_nfc_access(
+ object, invocation, result);
+
+ return true;
+
+ERR :
+ g_dbus_method_invocation_return_dbus_error(
+ invocation,
+ "org.tizen.SmartcardService.AccessControl.Error",
+ error);
+
+ return false;
+}
+
+static void _process_is_authorized_nfc_access(vector<void *> ¶ms)
+{
+ SmartcardServiceAccessControl *object;
+ GDBusMethodInvocation *invocation;
+ guint se_type;
+ gchar *package;
+ GVariant *aid;
+ void *user_data;
+
+ if (params.size() != 6) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceAccessControl *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ se_type = (guint)params[2];
+ package = (gchar *)params[3];
+ aid = (GVariant *)params[4];
+ user_data = params[5];
+
+ __process_is_authorized_nfc_access(object, invocation, se_type,
+ package, aid, user_data);
+
+ g_variant_unref(aid);
+
+ g_free(package);
+
+ g_object_unref(invocation);
+ g_object_unref(object);
+
+ /* FIXME : disable killing process code */
+// ServerResource::getInstance().finish();
+}
+
+static gboolean _handle_is_authorized_nfc_access(
+ SmartcardServiceAccessControl *object,
+ GDBusMethodInvocation *invocation,
+ guint se_type,
+ const gchar *package,
+ GVariant *aid,
+ void *user_data)
+{
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "r") == true) {
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)se_type);
+ params.push_back((void *)g_strdup(package));
+
+ g_variant_ref(aid);
+ params.push_back((void *)aid);
+
+ params.push_back((void *)user_data);
+
+ GDBusDispatcher::getInstance().push(
+ _process_is_authorized_nfc_access,
+ params);
+ } else {
+ _ERR("access denied");
+
+ g_dbus_method_invocation_return_dbus_error(
+ invocation,
+ "org.tizen.SmartcardService.AccessControl.Error",
+ "access denied");
+
+ /* FIXME : disable killing process code */
+// ServerResource::getInstance().finish();
+ }
+
+ return true;
+}
+
+static bool __load_cdf_acl(Terminal *terminal)
+{
+ bool result = false;
+ ServerResource &resource = ServerResource::getInstance();
+ ServerChannel *channel;
+
+ if (terminal == NULL) {
+ return result;
+ }
+
+// if (terminal->open() == SCARD_ERROR_OK) {
+ channel = resource.createInternalChannel(terminal, 1);
+ if (channel != NULL) {
+ int ret;
+
+ ret = cdfAcl.updateACL(channel);
+ if (ret == 0) {
+ result = true;
+ } else {
+ _ERR("acl is null");
+ result = false;
+ }
+
+ delete channel;
+ } else {
+ _ERR("alloc failed");
+ }
+//
+// terminal->close();
+// } else {
+// _ERR("terminal open failed");
+// }
+
+ return result;
+}
+
+static gboolean __process_is_authorized_extra_access(
+ SmartcardServiceAccessControl *object,
+ GDBusMethodInvocation *invocation,
+ guint se_type,
+ const gchar *package,
+ void *user_data)
+{
+ bool result = false;
+ const char *error;
+ const char *name;
+ char se[10];
+ pid_t pid;
+
+ ByteArray temp;
+ Terminal *terminal;
+ vector<ByteArray> hashes;
+
+ _INFO("[MSG_IS_AUTHORIZED_EXTRA_ACCESS]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ name = g_dbus_method_invocation_get_sender(invocation);
+
+ pid = ServerGDBus::getInstance().getPID(name);
+
+ _INFO("service requested, pid [%d]", pid);
+
+ if (pid < 0) {
+ error = "invalid pid";
+
+ _ERR("%s, [%d]", error, pid);
+
+ goto ERR;
+ }
+
+ /* check process permission */
+ if (_check_permission(pid) == false) {
+ error = "permission denied";
+
+ _ERR("%s, [%d]", error, pid);
+
+ goto ERR;
+ }
+
+ /* load secure elements */
+ resource.loadSecureElements();
+
+ if (_get_se_name(se_type, se, sizeof(se)) == false) {
+ error = "unknown SE type";
+
+ _ERR("%s, [%d]", error, se_type);
+
+ goto ERR;
+ }
+
+ _INFO("SE : [%s]", se);
+
+ terminal = resource.getTerminal(se);
+ if (terminal == NULL) {
+ error = "failed getting terminal";
+
+ _ERR("%s, [%d]", error, se_type);
+
+ goto ERR;
+ }
+
+ if (terminal->isSecureElementPresence() == false) {
+ error = "terminal is not available now";
+
+ _ERR("%s, [%d]", error, se_type);
+
+ goto ERR;
+ }
+
+ /* get certificate hashes */
+ if (SignatureHelper::getCertificationHashes(package, hashes) == false) {
+ error = "failed getting certificates";
+
+ _ERR("%s, [%s]", error, package);
+
+ goto ERR;
+ }
+
+ if ((se_type & 0xF0) == 0x10/* SIM */) {
+ /* load CDF */
+ if (cdfAcl.hasConditions() == false) {
+ _ERR("cdf rule doesn't be load");
+ __load_cdf_acl(terminal);
+ }
+
+ /* check access */
+ result = cdfAcl.isAuthorizedAccess(
+ AccessControlList::ALL_SE_APPS, hashes);
+ } else if ((se_type & 0xF0) == 0x20/* eSE */) {
+ if (terminal->open() == true) {
+ result = resource.isAuthorizedAccess(terminal,
+ AccessControlList::ALL_SE_APPS, hashes);
+
+ terminal->close();
+ }
+ }
+
+ /* response to client */
+ smartcard_service_access_control_complete_is_authorized_extra_access(
+ object, invocation, result);
+
+ return true;
+
+ERR :
+ g_dbus_method_invocation_return_dbus_error(
+ invocation,
+ "org.tizen.SmartcardService.AccessControl.Error",
+ error);
+
+ return false;
+}
+
+static void _process_is_authorized_extra_access(vector<void *> ¶ms)
+{
+ SmartcardServiceAccessControl *object;
+ GDBusMethodInvocation *invocation;
+ guint se_type;
+ gchar *package;
+ void *user_data;
+
+ if (params.size() != 5) {
+ _ERR("invalid parameter");
+
+ return;
+ }
+
+ object = (SmartcardServiceAccessControl *)params[0];
+ invocation = (GDBusMethodInvocation *)params[1];
+ se_type = (guint)params[2];
+ package = (gchar *)params[3];
+ user_data = params[4];
+
+ __process_is_authorized_extra_access(object, invocation, se_type,
+ package, user_data);
+
+ g_free(package);
+
+ g_object_unref(invocation);
+ g_object_unref(object);
+
+ /* FIXME : disable killing process code */
+// ServerResource::getInstance().finish();
+}
+
+static gboolean _handle_is_authorized_extra_access(
+ SmartcardServiceAccessControl *object,
+ GDBusMethodInvocation *invocation,
+ guint se_type,
+ const gchar *package,
+ void *user_data)
+{
+ vector<void *> params;
+
+ /* apply user space smack */
+ if (_is_authorized_request(invocation, "r") == true) {
+ g_object_ref(object);
+ params.push_back((void *)object);
+
+ g_object_ref(invocation);
+ params.push_back((void *)invocation);
+
+ params.push_back((void *)se_type);
+ params.push_back((void *)g_strdup(package));
+
+ params.push_back((void *)user_data);
+
+ GDBusDispatcher::getInstance().push(
+ _process_is_authorized_extra_access,
+ params);
+ } else {
+ _ERR("access denied");
+
+ g_dbus_method_invocation_return_dbus_error(
+ invocation,
+ "org.tizen.SmartcardService.AccessControl.Error",
+ "access denied");
+
+ /* FIXME : disable killing process code */
+// ServerResource::getInstance().finish();
+ }
+
+ return true;
+}
+
+static bool _init_access_control(void *connection)
+{
+ GError *error = NULL;
+
+ access_control = smartcard_service_access_control_skeleton_new();
+
+ g_signal_connect(access_control,
+ "handle-is-authorized-nfc-access",
+ G_CALLBACK(_handle_is_authorized_nfc_access),
+ NULL);
+
+ g_signal_connect(access_control,
+ "handle-is-authorized-extra-access",
+ G_CALLBACK(_handle_is_authorized_extra_access),
+ NULL);
+
+ if (g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(access_control),
+ (GDBusConnection *)connection,
+ "/org/tizen/SmartcardService/AccessControl",
+ &error) == false)
+ {
+ _ERR("Can not skeleton_export %s", error->message);
+
+ g_error_free(error);
+ g_object_unref(access_control);
+ access_control = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+static void _deinit_access_control()
+{
+ if (access_control != NULL) {
+ g_object_unref(access_control);
+ access_control = NULL;
+ }
+}
+
+extern "C" bool smartcard_service_init_access_control(void *connection)
+{
+ _load_granted_package_info();
+
+ return _init_access_control(connection);
+}
+
+extern "C" void smartcard_service_deinit_access_control()
+{
+ _deinit_access_control();
+}
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "PKCS15CDFACL.h"
+#include "PKCS15ODF.h"
+#include "OpensslHelper.h"
+#include "AccessCondition.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ PKCS15CDFACL::PKCS15CDFACL() : AccessControlList()
+ {
+ }
+
+ PKCS15CDFACL::~PKCS15CDFACL()
+ {
+ }
+
+ int PKCS15CDFACL::loadACL(Channel *channel)
+ {
+ int result = SCARD_ERROR_OK;
+
+ _BEGIN();
+
+ if (channel == NULL)
+ {
+ return SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ releaseACL();
+
+ PKCS15 pkcs15(channel);
+
+ result = pkcs15.select();
+ if (result >= SCARD_ERROR_OK)
+ {
+ PKCS15ODF *odf;
+
+ result = SCARD_ERROR_OK;
+
+ if ((odf = pkcs15.getODF()) != NULL)
+ {
+ PKCS15CDF *cdf;
+
+ cdf = odf->getCDF();
+ if (cdf != NULL)
+ {
+ result = loadRules(channel, cdf);
+ if (result == SCARD_ERROR_OK)
+ {
+ printAccessControlList();
+ }
+ else
+ {
+ result = SCARD_ERROR_OK;
+ }
+ }
+ else
+ {
+ _ERR("dodf null, every request will be denied.");
+ }
+ }
+ else
+ {
+ _ERR("odf null, every request will be denied.");
+ }
+ }
+ else
+ {
+ _ERR("failed to open PKCS#15, every request will be denied.");
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int PKCS15CDFACL::loadRules(Channel *channel, PKCS15CDF *cdf)
+ {
+ int result = 0;
+ size_t i;
+ ByteArray hash;
+ const CertificateType *type;
+ AccessCondition condition;
+
+ condition.setAID(AccessControlList::ALL_SE_APPS);
+
+ for (i = 0; i < cdf->getCount(); i++) {
+ type = cdf->getCertificateType(i);
+
+ OpensslHelper::digestBuffer("SHA1", type->certificate, hash);
+
+ _INFO("cdf[%d] = %s", i, hash.toString().c_str());
+
+ condition.addAccessRule(hash);
+ }
+
+ pair<ByteArray, AccessCondition> newItem(
+ AccessControlList::ALL_SE_APPS, condition);
+
+ mapConditions.insert(newItem);
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
* limitations under the License.
*/
-#ifndef SERVERDISPATCHER_H_
-#define SERVERDISPATCHER_H_
+#ifndef PKCS15CDFACL_H_
+#define PKCS15CDFACL_H_
/* standard library header */
/* SLP library header */
/* local header */
-#include "DispatcherHelper.h"
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "AccessControlList.h"
+#include "PKCS15.h"
+#endif /* __cplusplus */
+#ifdef __cplusplus
namespace smartcard_service_api
{
- class ServerIPC;
-
- class ServerDispatcher: public DispatcherHelper
+ class PKCS15CDFACL : public AccessControlList
{
private:
- ServerDispatcher();
- ~ServerDispatcher();
-
- void *dispatcherThreadFunc(DispatcherMsg *msg, void *data);
+ int loadRules(Channel *channel, PKCS15CDF *cdf);
public:
- static ServerDispatcher *getInstance();
+ PKCS15CDFACL();
+ ~PKCS15CDFACL();
+
+ int loadACL(Channel *channel);
};
} /* namespace smartcard_service_api */
-#endif /* SERVERDISPATCHER_H_ */
+#endif /* __cplusplus */
+#endif /* PKCS15CDFACL_H_ */
--- /dev/null
+<!--
+ org.tizen.SmartcardService
+-->
+
+<node>
+ <interface name="org.tizen.SmartcardService.AccessControl">
+ <!--
+ isAuthorizedExtraAccess
+ -->
+ <method name="isAuthorizedExtraAccess">
+ <arg type="u" name="se_type" direction="in" />
+ <arg type="s" name="package" direction="in" />
+ <arg type="b" name="result" direction="out" />
+ </method>
+
+ <!--
+ isAuthorizedNfcAccess
+ -->
+ <method name="isAuthorizedNfcAccess">
+ <arg type="u" name="se_type" direction="in" />
+ <arg type="s" name="package" direction="in" />
+ <arg type="a(y)" name="aid" direction="in" />
+ <arg type="b" name="result" direction="out" />
+ </method>
+ </interface>
+</node>
#include <unistd.h>
#include <string.h>
#include <glib.h>
+#include <glib-object.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>
-#ifdef __cplusplus
#include <vector>
-#endif /* __cplusplus */
-#ifdef USE_AUTOSTART
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-bindings.h>
-#endif
/* SLP library header */
/* local header */
#include "Debug.h"
-#include "ServerIPC.h"
#include "ServerResource.h"
-#ifdef USE_AUTOSTART
-#include "SmartcardDbus.h"
-#include "smartcard-service-binding.h"
-#endif
+#include "smartcard-service-gdbus.h"
+#include "ServerGDBus.h"
/* definition */
-#ifdef __cplusplus
using namespace std;
using namespace smartcard_service_api;
-#endif /* __cplusplus */
/* global variable */
-#ifdef USE_AUTOSTART
-GObject *object = NULL;
-DBusGConnection *connection = NULL;
-#endif
+GMainLoop *main_loop = NULL;
#ifndef USE_AUTOSTART
static void daemonize(void)
}
#endif
-#ifdef USE_AUTOSTART
-G_DEFINE_TYPE(Smartcard_Service, smartcard_service, G_TYPE_OBJECT)
-
-/* Just Check the assert and set the error message */
-#define __G_ASSERT(test, return_val, error, domain, error_code)\
-G_STMT_START\
-{\
- if G_LIKELY (!(test)) { \
- g_set_error (error, domain, error_code, #test); \
- return (return_val); \
- }\
-}\
-G_STMT_END
-
-GQuark smartcard_service_error_quark(void)
-{
- SCARD_DEBUG("smartcard_service_error_quark entered");
-
- return g_quark_from_static_string("smartcard_service_error");
-}
-
-static void smartcard_service_init(Smartcard_Service *smartcard_service)
-{
- SCARD_DEBUG("smartcard_service_init entered");
-}
-
-static void smartcard_service_class_init(Smartcard_ServiceClass *smartcard_service_class)
+static void _bus_acquired_cb(GDBusConnection *connection,
+ const gchar *path, gpointer user_data)
{
- SCARD_DEBUG("smartcard_service_class_init entered");
+ _DBG("bus path : %s", path);
- dbus_g_object_type_install_info(SMARTCARD_SERVICE_TYPE, &dbus_glib_smartcard_service_object_info);
-}
+ ServerResource::getInstance();
-gboolean smartcard_service_launch(Smartcard_Service *smartcard_service, guint *result_val, GError **error)
-{
- SCARD_DEBUG("smartcard_service_launch entered");
-
- return TRUE;
+ ServerGDBus::getInstance().init();
}
-static void _initialize_dbus()
+static void _name_acquired_cb(GDBusConnection *connection,
+ const gchar *name, gpointer user_data)
{
- GError *error = NULL;
- DBusGProxy *proxy = NULL;
- guint ret = 0;
-
- SCARD_BEGIN();
-
- g_type_init();
-
- connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
- if (error == NULL)
- {
- object = (GObject *)g_object_new(SMARTCARD_SERVICE_TYPE, NULL);
- dbus_g_connection_register_g_object(connection, SMARTCARD_SERVICE_PATH, object);
-
- /* register service */
- proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
- if (proxy != NULL)
- {
- if (!org_freedesktop_DBus_request_name(proxy, SMARTCARD_SERVICE_NAME, 0, &ret, &error))
- {
- SCARD_DEBUG_ERR("Unable to register service: %s", error->message);
- g_error_free(error);
- }
-
- g_object_unref (proxy);
- }
- else
- {
- SCARD_DEBUG_ERR("dbus_g_proxy_new_for_name failed");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("ERROR: Can't get on system bus [%s]", error->message);
- g_error_free(error);
- }
-
- SCARD_END();
+ _DBG("name : %s", name);
}
-static void _finalize_dbus()
+static void _name_lost_cb(GDBusConnection *connnection,
+ const gchar *name, gpointer user_data)
{
- SCARD_BEGIN();
-
- dbus_g_connection_unregister_g_object(connection, object);
- g_object_unref(object);
+ _DBG("name : %s", name);
- SCARD_END();
+ ServerGDBus::getInstance().deinit();
}
-#endif
static void __sighandler(int sig)
{
- SCARD_DEBUG("signal!! [%d]", sig);
-
-#ifdef USE_AUTOSTART
- _finalize_dbus();
-#endif
+ _DBG("signal!! [%d]", sig);
}
-int main()
+int main(int argc, char *argv[])
{
- GMainLoop *loop = NULL;
-
+ guint id = 0;
signal(SIGTERM, &__sighandler);
#ifndef USE_AUTOSTART
daemonize();
#endif
- if (!g_thread_supported())
- {
+ if (!g_thread_supported()) {
g_thread_init(NULL);
}
- loop = g_main_new(TRUE);
+ g_type_init();
-#ifdef __cplusplus
- ServerResource::getInstance().setMainLoopInstance(loop);
- ServerIPC::getInstance()->createListenSocket();
-#else /* __cplusplus */
- server_resource_set_main_loop_instance(loop);
- server_ipc_create_listen_socket();
-#endif /* __cplusplus */
+ main_loop = g_main_new(TRUE);
-#ifdef USE_AUTOSTART
- _initialize_dbus();
-#endif
- g_main_loop_run(loop);
+ id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+ "org.tizen.SmartcardService",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ _bus_acquired_cb,
+ _name_acquired_cb,
+ _name_lost_cb,
+ NULL,
+ NULL);
+
+ g_main_loop_run(main_loop);
+
+ if (id)
+ g_bus_unown_name(id);
-#ifdef USE_AUTOSTART
- _finalize_dbus();
-#endif
/* release secure element.. (pure virtual function problem..) */
ServerResource::getInstance().unloadSecureElements();
return 0;
}
+
+void smartcard_daemon_exit()
+{
+ g_main_loop_quit(main_loop);
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" package="smartcard-service-server" version="0.1.20" install-location="internal-only" type="rpm">
+ <label>Smartcard Service Server</label>
+ <author email="constant.lee@samsung.com" href="www.samsung.com">Sangsoo Lee</author>
+ <author email="wonkyu.kwon@samsung.com" href="www.samsung.com">Wonkyu Kwon</author>
+ <description>Smartcard Service Server</description>
+ <ui-application appid="smartcard-service-server"
+ exec="/usr/apps/smartcard-service-server/bin/smartcard-daemon"
+ nodisplay="true"
+ multiple="false"
+ type="capp"
+ taskmanage="false"
+ mainapp="true">
+ <label>Smartcard Service Server</label>
+ </ui-application>
+</manifest>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<node name="/org/tizen/smartcard_service">
- <interface name="org.tizen.smartcard_service">
- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="smartcard_service"/>
- <method name="launch">
- <arg type="i" name="result" direction="out"/>
- </method>
- </interface>
-</node>
-
<manifest>
<define>
<domain name="smartcard-service" />
+ <provide>
+ <label name="smartcard-service::priv" />
+ </provide>
<request>
<smack request="sys-assert::core" type="rwxat" />
+ <smack request="nfc-manager" type="rwx" />
+ <smack request="csc-feature" type="r" />
+ <smack request="security-server::api-privilege-by-pid" type="w" />
</request>
</define>
<assign>
- <filesystem path="/usr/bin/smartcard-daemon" exec_label="nfc-manager" />
+ <filesystem path="/usr/apps/smartcard-service-server/bin/smartcard-daemon" exec_label="smartcard-service" />
+ <!-- <filesystem path="/usr/apps/smartcard-service-server/bin/smartcard-test-client" exec_label="smartcard-service" /> -->
<filesystem path="/usr/share/dbus-1/services/smartcard-service.service" label="_" />
</assign>
<request>
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
#AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ SRCS)
-#SET(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/test-client-async.cpp")
-SET(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/test-client.cpp")
+SET(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/test-client-sync.cpp")
+#SET(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/test-client.cpp")
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)
+pkg_check_modules(pkgs_test_client REQUIRED glib-2.0 dlog)
FOREACH(flag ${pkgs_test_client_CFLAGS})
SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
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)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/apps/smartcard-service-server/bin)
{
void serviceConnected(SEServiceHelper *service, void *userData)
{
- SCARD_BEGIN();
+ _BEGIN();
testConnectedCallback(service, userData);
- SCARD_END();
+ _END();
}
void eventHandler(SEServiceHelper *service, char *seName, int event, void *userData)
{
- SCARD_BEGIN();
+ _BEGIN();
- SCARD_DEBUG("event occured service [%p], seName[%p], event [%d]", service, seName, event);
+ _INFO("event occurred service [%p], seName[%p], event [%d]", service, seName, event);
- SCARD_END();
+ _END();
}
void errorHandler(SEServiceHelper *service, int error, void *userData)
{
- SCARD_BEGIN();
+ _BEGIN();
- SCARD_DEBUG("error occured service [%p], error [%d]", service, error);
+ _ERR("error occurred service [%p], error [%d]", service, error);
- SCARD_END();
+ _END();
}
};
{
vector<ReaderHelper *> readers;
user_context_t *context = (user_context_t *)userData;
+ uint8_t buffer[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
+// uint8_t buffer[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
- SCARD_BEGIN();
+ _BEGIN();
if (service != NULL)
{
- SCARD_DEBUG("callback called, service [%p]", service);
+ _DBG("callback called, service [%p]", service);
context->clientService = service;
readers = service->getReaders();
- if (readers.size() > 0)
+ size_t i;
+ for (i = 0; i < readers.size(); i++)
{
Reader *reader = NULL;
- reader = (Reader *)readers[0];
+ reader = (Reader *)readers[i];
- SCARD_DEBUG("reader [%p]", reader);
+ _DBG("reader [%p]", reader);
Session *session = (Session *)reader->openSessionSync();
if (session != NULL)
{
- SCARD_DEBUG("session [%p]", session);
+ _DBG("session [%p]", session);
ByteArray temp;
- temp = session->getATRSync();
- SCARD_DEBUG("atr[%d] : %s", temp.getLength(), temp.toString());
+ try
+ {
+ temp = session->getATRSync();
+ }
+ catch (...)
+ {
+ _ERR("exception....");
+ }
+ _DBG("atr[%d] : %s", temp.size(), temp.toString().c_str());
- unsigned char MF[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
ByteArray aid;
- aid.setBuffer(MF, sizeof(MF));
- ClientChannel *channel = (ClientChannel *)session->openLogicalChannelSync(aid);
- if (channel != NULL)
+ aid.assign(buffer, sizeof(buffer));
+ try
{
- SCARD_DEBUG("channel [%p]", channel);
- ByteArray response;
- ByteArray data, command;
- int fid = 0x00003150;
-
- 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);
- int error = channel->transmitSync(command, response);
-
- SCARD_DEBUG("error : %d, response : %s", error, response.toString());
-
- channel->closeSync();
+ ClientChannel *channel = (ClientChannel *)session->openLogicalChannelSync(aid);
+ if (channel != NULL)
+ {
+ _DBG("channel [%p]", channel);
+ ByteArray response;
+ ByteArray data, command;
+ int fid = 0x00003150;
+
+ response = channel->getSelectResponse();
+ _INFO("response : %s", response.toString().c_str());
+
+ _DBG("isBasicChannel() = %s", channel->isBasicChannel() ? "Basic" : "Logical");
+ _DBG("isClosed() = %s", channel->isClosed() ? "Closed" : "Opened");
+
+ data.assign((unsigned char *)&fid, 2);
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, data);
+ int error = channel->transmitSync(command, response);
+
+ _INFO("error : %d, response : %s", error, response.toString().c_str());
+
+ channel->closeSync();
+ }
+ else
+ {
+ _ERR("openLogicalChannelSync failed");
+ }
}
- else
+ catch (...)
{
- SCARD_DEBUG_ERR("openLogicalChannelSync failed");
+ _ERR("exception....");
}
session->closeSync();
}
else
{
- SCARD_DEBUG_ERR("openSessionSync failed");
+ _ERR("openSessionSync failed");
}
-
- service->shutdown();
- }
- else
- {
- SCARD_DEBUG_ERR("reader is empty");
}
+
+ ((SEService *)service)->shutdownSync();
}
else
{
- SCARD_DEBUG_ERR("service is NULL");
+ _ERR("service is NULL");
}
g_main_loop_quit(loop);
- SCARD_END();
+ _END();
}
int main(int argv, char *args[])
{
void serviceConnected(SEServiceHelper *service, void *userData)
{
- SCARD_BEGIN();
+ _BEGIN();
testConnectedCallback(service, userData);
- SCARD_END();
+ _END();
}
void eventHandler(SEServiceHelper *service, char *seName, int event, void *userData)
vector<ReaderHelper *> readers;
size_t i;
- SCARD_BEGIN();
+ _BEGIN();
- SCARD_DEBUG("event occured service [%p], seName[%s], event [%d], userData [%p]", service, seName, event, userData);
+ _INFO("event occurred service [%p], seName[%s], event [%d], userData [%p]", service, seName, event, userData);
readers = service->getReaders();
for (i = 0; i < readers.size(); i++)
{
- SCARD_DEBUG("Reader[%d] : name [%s], %s", i, readers[i]->getName(), readers[i]->isSecureElementPresent() ? "available" : "unavailable");
+ _DBG("Reader[%d] : name [%s], %s", i, readers[i]->getName(), readers[i]->isSecureElementPresent() ? "available" : "unavailable");
}
if (event == 1)
testConnectedCallback(service, userData);
}
- SCARD_END();
+ _END();
}
void errorHandler(SEServiceHelper *service, int error, void *userData)
{
- SCARD_BEGIN();
+ _BEGIN();
- SCARD_DEBUG("error occured service [%p], error [%d]", service, error);
+ _ERR("error occurred service [%p], error [%d]", service, error);
- SCARD_END();
+ _END();
}
};
{
user_context_t *context = (user_context_t *)userData;
- SCARD_DEBUG("result [%d], userData [%p]", error, userData);
+ _DBG("result [%d], userData [%p]", error, userData);
context->clientService->shutdown();
}
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);
+ _DBG("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);
+ _DBG("channel [%p]", channel);
if (error == 0 && channel != NULL)
{
response = channel->getSelectResponse();
- SCARD_DEBUG("response : %s", response.toString());
+ _INFO("response : %s", response.toString().c_str());
- SCARD_DEBUG("isBasicChannel() = %s", channel->isBasicChannel() ? "Basic" : "Logical");
- SCARD_DEBUG("isClosed() = %s", channel->isClosed() ? "Closed" : "Opened");
+ _DBG("isBasicChannel() = %s", channel->isBasicChannel() ? "Basic" : "Logical");
+ _DBG("isClosed() = %s", channel->isClosed() ? "Closed" : "Opened");
- data.setBuffer((unsigned char *)&fid, 2);
+ data.assign((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");
+ _ERR("openBasicChannel failed");
}
}
ByteArray aid, result(atr, length);
user_context_t *context = (user_context_t *)userData;
- SCARD_DEBUG("atr[%d] : %s", result.getLength(), result.toString());
+ _DBG("atr[%d] : %s", result.size(), result.toString().c_str());
- aid.setBuffer(MF, sizeof(MF));
+ aid.assign(MF, sizeof(MF));
context->clientSession->openLogicalChannel(aid, testOpenChannelCallback, userData);
}
void testOpenSessionCallback(SessionHelper *session, int error, void *userData)
{
- SCARD_DEBUG("session [%p]", session);
+ _DBG("session [%p]", session);
if (session != NULL)
{
}
else
{
- SCARD_DEBUG_ERR("openSession failed");
+ _ERR("openSession failed");
}
}
vector<ReaderHelper *> readers;
user_context_t *context = (user_context_t *)userData;
- SCARD_BEGIN();
+ _BEGIN();
if (service != NULL)
{
- SCARD_DEBUG("callback called, service [%p]", service);
+ _DBG("callback called, service [%p]", service);
context->clientService = service;
reader = (Reader *)readers[0];
- SCARD_DEBUG("reader [%p]", reader);
+ _DBG("reader [%p]", reader);
reader->openSession(testOpenSessionCallback, userData);
}
else
{
- SCARD_DEBUG_ERR("reader is empty");
+ _ERR("reader is empty");
}
}
else
{
- SCARD_DEBUG_ERR("service is NULL");
+ _ERR("service is NULL");
}
- SCARD_END();
+ _END();
}
int main(int argv, char *args[])
}
catch (...)
{
- SCARD_DEBUG_ERR("exception raised!!!");
+ _ERR("exception raised!!!");
}
if (service != NULL)