2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <system_info.h>
24 #include "smartcard.h"
25 #include "smartcard_debug.h"
27 #ifdef TIZEN_SMARTCARD_SUPPORT
28 #include "smartcard-service.h"
30 #define SE_FEATURE "http://tizen.org/feature/network.secure_element"
31 #define SE_UICC_FEATURE "http://tizen.org/feature/network.secure_element.uicc"
32 #define SE_ESE_FEATURE "http://tizen.org/feature/network.secure_element.ese"
34 #define SMARTCARD_LOCK \
36 pthread_mutex_lock(&mutex); \
39 #define SMARTCARD_UNLOCK \
41 pthread_mutex_unlock(&mutex); \
44 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
47 se_service_h se_service;
48 bool _is_initialize = false;
54 #define CHECK_SUPPORTED() \
57 if (_is_smartcard_supported() == false) { \
58 return SMARTCARD_ERROR_NOT_SUPPORTED; \
64 #define CHECK_INIT() \
68 if (_is_initialize == false) { \
70 return SMARTCARD_ERROR_NOT_INITIALIZED; \
76 static bool _is_smartcard_supported()
79 bool is_supported_se = false;
80 bool is_supported_se_uicc = false;
81 bool is_supported_se_ese = false;
83 system_info_get_platform_bool(SE_FEATURE, &is_supported_se);
84 system_info_get_platform_bool(SE_UICC_FEATURE, &is_supported_se_uicc);
85 system_info_get_platform_bool(SE_ESE_FEATURE, &is_supported_se_ese);
87 if (is_supported_se && (is_supported_se_uicc || is_supported_se_ese))
93 static int _check_precondition_reader(int handle)
98 if (g_list_find(g_list_first(reader_list), GINT_TO_POINTER(handle)) == NULL) {
100 return SMARTCARD_ERROR_INVALID_PARAMETER;
104 return SMARTCARD_ERROR_NONE;
107 static int _check_precondition_session(int handle)
112 if (g_list_find(g_list_first(session_list), GINT_TO_POINTER(handle)) == NULL) {
114 return SMARTCARD_ERROR_INVALID_PARAMETER;
118 return SMARTCARD_ERROR_NONE;
121 static int _check_precondition_channel(int handle)
126 if (g_list_find(g_list_first(channel_list), GINT_TO_POINTER(handle)) == NULL) {
128 return SMARTCARD_ERROR_INVALID_PARAMETER;
130 /* LCOV_EXCL_START */
133 return SMARTCARD_ERROR_NONE;
137 static smartcard_error_e _convert_error_code(const char *func, int native_error_code)
139 smartcard_error_e error_code = SMARTCARD_ERROR_NONE;
140 char *errorstr = NULL;
142 switch (native_error_code) {
144 error_code = SMARTCARD_ERROR_NONE;
145 errorstr = "SMARTCARD_ERROR_NONE";
147 case SCARD_ERROR_NOT_SUPPORTED:
148 /* LCOV_EXCL_START */
149 error_code = SMARTCARD_ERROR_OPERATION_NOT_SUPPORTED;
150 errorstr = "SMARTCARD_ERROR_OPERATION_NOT_SUPPORTED";
153 case SCARD_ERROR_UNAVAILABLE:
154 /* LCOV_EXCL_START */
155 error_code = SMARTCARD_ERROR_CHANNEL_NOT_AVAILABLE;
156 errorstr = "SMARTCARD_ERROR_CHANNEL_NOT_AVAILABLE";
159 case SCARD_ERROR_IPC_FAILED:
160 case SCARD_ERROR_IO_FAILED:
161 /* LCOV_EXCL_START */
162 error_code = SMARTCARD_ERROR_IO_ERROR;
163 errorstr = "SMARTCARD_ERROR_IO_ERROR";
166 case SCARD_ERROR_SECURITY_NOT_ALLOWED:
167 /* LCOV_EXCL_START */
168 error_code = SMARTCARD_ERROR_PERMISSION_DENIED;
169 errorstr = "SMARTCARD_ERROR_PERMISSION_DENIED";
172 case SCARD_ERROR_ILLEGAL_STATE:
173 /* LCOV_EXCL_START */
174 error_code = SMARTCARD_ERROR_ILLEGAL_STATE;
175 errorstr = "SMARTCARD_ERROR_ILLEGAL_STATE";
178 case SCARD_ERROR_ILLEGAL_PARAM:
179 /* LCOV_EXCL_START */
180 error_code = SMARTCARD_ERROR_INVALID_PARAMETER;
181 errorstr = "SMARTCARD_ERROR_INVALID_PARAMETER";
184 case SCARD_ERROR_ILLEGAL_REFERENCE:
185 /* LCOV_EXCL_START */
186 error_code = SMARTCARD_ERROR_ILLEGAL_REFERENCE;
187 errorstr = "SMARTCARD_ERROR_ILLEGAL_REFERENCE";
190 case SCARD_ERROR_NOT_INITIALIZED:
191 case SCARD_ERROR_SE_NOT_INITIALIZED:
192 case SCARD_ERROR_OPERATION_NOT_SUPPORTED:
193 case SCARD_ERROR_NEED_MORE_BUFFER:
194 case SCARD_ERROR_OPERATION_TIMEOUT:
195 case SCARD_ERROR_NOT_ENOUGH_RESOURCE:
196 case SCARD_ERROR_OUT_OF_MEMORY:
197 case SCARD_ERROR_UNKNOWN:
199 /* LCOV_EXCL_START */
200 error_code = SMARTCARD_ERROR_GENERAL;
201 errorstr = "SMARTCARD_ERROR_GENERAL";
205 _ERR("smartcard func : %s, %s(0x%08x)\n", func, errorstr, error_code);
211 /* managing apis : initaialize, deinitialize */
213 int smartcard_initialize(void)
215 #ifndef TIZEN_SMARTCARD_SUPPORT
216 return SMARTCARD_ERROR_NOT_SUPPORTED;
218 int ret = SMARTCARD_ERROR_NONE;
225 if (se_service == NULL || ref_count > 0) {
226 /* create se service instance. */
227 se_service = se_service_create_instance_sync(NULL, &ret);
228 if (se_service == NULL || ret != SCARD_ERROR_OK) {
229 SMARTCARD_UNLOCK; /* LCOV_EXCL_LINE */
230 if (ret == SCARD_ERROR_SECURITY_NOT_ALLOWED) /* LCOV_EXCL_LINE */
231 return SMARTCARD_ERROR_PERMISSION_DENIED;
233 return SMARTCARD_ERROR_GENERAL; /* LCOV_EXCL_LINE */
236 _is_initialize = true;
244 return _convert_error_code(__func__, ret);
248 int smartcard_deinitialize(void)
250 #ifndef TIZEN_SMARTCARD_SUPPORT
251 return SMARTCARD_ERROR_NOT_SUPPORTED;
253 int ret = SMARTCARD_ERROR_NONE;
264 return SMARTCARD_ERROR_NOT_INITIALIZED;
267 if (se_service != NULL && ref_count == 0) {
268 se_service_shutdown(se_service);
270 /* destroy se service instance. */
271 ret = se_service_destroy_instance(se_service);
272 if (ret != SCARD_ERROR_OK) {
273 /* LCOV_EXCL_START */
275 return SMARTCARD_ERROR_GENERAL;
280 g_list_free(reader_list);
281 g_list_free(session_list);
282 g_list_free(channel_list);
286 _is_initialize = false;
293 return _convert_error_code(__func__, ret);
298 /*----------------<SE Service mapping api>------------------*/
300 int smartcard_get_readers(int **readers, int *length)
302 #ifndef TIZEN_SMARTCARD_SUPPORT
303 return SMARTCARD_ERROR_NOT_SUPPORTED;
306 int ret = SMARTCARD_ERROR_NONE;
310 /* precondition check start */
314 cond_expr_ret(NULL == readers, SMARTCARD_ERROR_INVALID_PARAMETER);
315 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
317 /* precondition check end */
321 ret = se_service_get_readers(se_service, readers, length);
325 for (i = 0; i < *length; i++) {
328 if (g_list_find(g_list_first(reader_list), GINT_TO_POINTER(*(readers[i]))) == NULL)
329 reader_list = g_list_append(reader_list, GINT_TO_POINTER(*(readers[i])));
336 return _convert_error_code(__func__, ret);
340 /*----------------<reader mapping api>------------------*/
342 int smartcard_reader_get_name(int reader, char **reader_name)
344 #ifndef TIZEN_SMARTCARD_SUPPORT
345 return SMARTCARD_ERROR_NOT_SUPPORTED;
347 int ret = SMARTCARD_ERROR_NONE;
351 /* precondition check start */
355 cond_expr_ret(NULL == reader_name, SMARTCARD_ERROR_INVALID_PARAMETER);
357 ret = _check_precondition_reader(reader);
360 /* precondition check end */
363 ret = reader_get_name((reader_h)reader, reader_name);
365 if (ret != SCARD_ERROR_OK || strlen(*reader_name) == 0)
366 return SMARTCARD_ERROR_GENERAL;
370 return SMARTCARD_ERROR_NONE;
374 int smartcard_reader_is_secure_element_present(int reader, bool *is_present)
376 #ifndef TIZEN_SMARTCARD_SUPPORT
377 return SMARTCARD_ERROR_NOT_SUPPORTED;
379 int ret = SMARTCARD_ERROR_NONE;
383 /* precondition check start */
387 cond_expr_ret(NULL == is_present, SMARTCARD_ERROR_INVALID_PARAMETER);
389 ret = _check_precondition_reader(reader);
392 /* precondition check end */
394 ret = reader_is_secure_element_present((reader_h)reader, is_present);
398 return _convert_error_code(__func__, ret);
402 int smartcard_reader_open_session(int reader, int *session)
404 #ifndef TIZEN_SMARTCARD_SUPPORT
405 return SMARTCARD_ERROR_NOT_SUPPORTED;
407 int ret = SMARTCARD_ERROR_NONE;
411 /* precondition check start */
415 ret = _check_precondition_reader(reader);
418 cond_expr_ret(NULL == session, SMARTCARD_ERROR_INVALID_PARAMETER);
420 /* precondition check end */
422 ret = reader_open_session_sync((reader_h)reader, session);
424 if (ret == SCARD_ERROR_OK) {
426 if (g_list_find(g_list_first(session_list), GINT_TO_POINTER(*session)) == NULL)
427 session_list = g_list_append(session_list, GINT_TO_POINTER(*session));
433 return _convert_error_code(__func__, ret);
437 int smartcard_reader_close_sessions(int reader)
439 #ifndef TIZEN_SMARTCARD_SUPPORT
440 return SMARTCARD_ERROR_NOT_SUPPORTED;
442 int ret = SMARTCARD_ERROR_NONE;
446 /* precondition check start */
450 ret = _check_precondition_reader(reader);
453 /* precondition check end */
455 ret = reader_close_sessions((reader_h)reader);
459 return _convert_error_code(__func__, ret);
463 /*----------------<session mapping api>------------------*/
465 int smartcard_session_get_reader(int session, int *reader)
467 #ifndef TIZEN_SMARTCARD_SUPPORT
468 return SMARTCARD_ERROR_NOT_SUPPORTED;
470 int ret = SMARTCARD_ERROR_NONE;
474 /* precondition check start */
478 cond_expr_ret(NULL == reader, SMARTCARD_ERROR_INVALID_PARAMETER);
480 ret = _check_precondition_session(session);
483 /* precondition check end */
485 ret = session_get_reader((session_h)session, reader);
489 return _convert_error_code(__func__, ret);
493 int smartcard_session_get_atr(int session, unsigned char **atr, int *length)
495 #ifndef TIZEN_SMARTCARD_SUPPORT
496 return SMARTCARD_ERROR_NOT_SUPPORTED;
498 int ret = SMARTCARD_ERROR_NONE;
502 /* precondition check start */
506 cond_expr_ret(NULL == atr, SMARTCARD_ERROR_INVALID_PARAMETER);
507 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
509 ret = _check_precondition_session(session);
515 /* precondition check end */
516 ret = session_get_atr_sync((session_h)session, atr, (unsigned int *)length);
518 if (ret == SCARD_ERROR_OK) {
519 if (((*atr == NULL) && (*length != 0)) ||
520 ((*atr != NULL) && (*length == 0))) {
521 return SMARTCARD_ERROR_GENERAL;
527 return _convert_error_code(__func__, ret);
531 int smartcard_session_close(int session)
533 #ifndef TIZEN_SMARTCARD_SUPPORT
534 return SMARTCARD_ERROR_NOT_SUPPORTED;
536 int ret = SMARTCARD_ERROR_NONE;
540 /* precondition check start */
544 ret = _check_precondition_session(session);
547 /* precondition check end */
549 ret = session_close_sync((session_h)session);
553 return _convert_error_code(__func__, ret);
557 int smartcard_session_is_closed(int session, bool *is_closed)
559 #ifndef TIZEN_SMARTCARD_SUPPORT
560 return SMARTCARD_ERROR_NOT_SUPPORTED;
562 int ret = SMARTCARD_ERROR_NONE;
566 /* precondition check start */
570 cond_expr_ret(NULL == is_closed, SMARTCARD_ERROR_INVALID_PARAMETER);
572 ret = _check_precondition_session(session);
575 /* precondition check end */
577 ret = session_is_closed((session_h)session, is_closed);
581 return _convert_error_code(__func__, ret);
585 int smartcard_session_close_channels(int session)
587 #ifndef TIZEN_SMARTCARD_SUPPORT
588 return SMARTCARD_ERROR_NOT_SUPPORTED;
590 int ret = SMARTCARD_ERROR_NONE;
594 /* precondition check start */
598 ret = _check_precondition_session(session);
601 /* precondition check end */
603 ret = session_close_channels((session_h)session);
607 return _convert_error_code(__func__, ret);
611 int smartcard_session_open_basic_channel(int session, unsigned char *aid, int aid_len,
612 unsigned char P2, int *channel)
614 #ifndef TIZEN_SMARTCARD_SUPPORT
615 return SMARTCARD_ERROR_NOT_SUPPORTED;
617 int ret = SMARTCARD_ERROR_NONE;
621 /* precondition check start */
625 cond_expr_ret(NULL == channel, SMARTCARD_ERROR_INVALID_PARAMETER);
627 /* LCOV_EXCL_START */
628 ret = _check_precondition_session(session);
631 /* precondition check end */
633 ret = session_open_basic_channel_sync((session_h)session, aid, aid_len, P2, channel);
635 if (ret == SCARD_ERROR_OK) {
637 if (g_list_find(g_list_first(channel_list), GINT_TO_POINTER(*channel)) == NULL)
638 channel_list = g_list_append(channel_list, GINT_TO_POINTER(*channel));
644 return _convert_error_code(__func__, ret);
649 int smartcard_session_open_logical_channel(int session, unsigned char *aid, int aid_len,
650 unsigned char P2, int *channel)
652 #ifndef TIZEN_SMARTCARD_SUPPORT
653 return SMARTCARD_ERROR_NOT_SUPPORTED;
655 int ret = SMARTCARD_ERROR_NONE;
659 /* precondition check start */
663 cond_expr_ret(NULL == channel, SMARTCARD_ERROR_INVALID_PARAMETER);
665 /* LCOV_EXCL_START */
666 ret = _check_precondition_session(session);
669 /* precondition check end */
671 ret = session_open_logical_channel_sync((session_h)session, aid, aid_len, P2, channel);
673 if (ret == SCARD_ERROR_OK) {
675 if (g_list_find(g_list_first(channel_list), GINT_TO_POINTER(*channel)) == NULL)
676 channel_list = g_list_append(channel_list, GINT_TO_POINTER(*channel));
682 return _convert_error_code(__func__, ret);
687 /*----------------<channel mapping api>------------------*/
689 int smartcard_channel_close(int channel)
691 #ifndef TIZEN_SMARTCARD_SUPPORT
692 return SMARTCARD_ERROR_NOT_SUPPORTED;
694 int ret = SMARTCARD_ERROR_NONE;
698 /* precondition check start */
702 ret = _check_precondition_channel(channel);
705 /* precondition check end */
706 /* LCOV_EXCL_START */
707 ret = channel_close_sync((channel_h)channel);
711 return _convert_error_code(__func__, ret);
716 int smartcard_channel_is_basic_channel(int channel, bool *is_basic_channel)
718 #ifndef TIZEN_SMARTCARD_SUPPORT
719 return SMARTCARD_ERROR_NOT_SUPPORTED;
721 int ret = SMARTCARD_ERROR_NONE;
725 /* precondition check start */
729 cond_expr_ret(NULL == is_basic_channel, SMARTCARD_ERROR_INVALID_PARAMETER);
731 /* LCOV_EXCL_START */
732 ret = _check_precondition_channel(channel);
735 /* precondition check end */
737 ret = channel_is_basic_channel((channel_h)channel, is_basic_channel);
741 return _convert_error_code(__func__, ret);
746 int smartcard_channel_is_closed(int channel, bool *is_closed)
748 #ifndef TIZEN_SMARTCARD_SUPPORT
749 return SMARTCARD_ERROR_NOT_SUPPORTED;
751 int ret = SMARTCARD_ERROR_NONE;
755 /* precondition check start */
759 cond_expr_ret(NULL == is_closed, SMARTCARD_ERROR_INVALID_PARAMETER);
761 /* LCOV_EXCL_START */
762 ret = _check_precondition_channel(channel);
765 /* precondition check end */
767 ret = channel_is_closed((channel_h)channel, is_closed);
771 return _convert_error_code(__func__, ret);
776 int smartcard_channel_get_select_response(int channel, unsigned char **select_resp,
779 #ifndef TIZEN_SMARTCARD_SUPPORT
780 return SMARTCARD_ERROR_NOT_SUPPORTED;
783 int ret = SMARTCARD_ERROR_NONE;
787 /* precondition check start */
791 cond_expr_ret(NULL == select_resp, SMARTCARD_ERROR_INVALID_PARAMETER);
792 /* LCOV_EXCL_START */
793 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
795 ret = _check_precondition_channel(channel);
798 /* precondition check end */
800 ret = channel_get_select_response((channel_h)channel, select_resp, &s_length);
801 *length = (int)s_length;
805 return _convert_error_code(__func__, ret);
810 int smartcard_channel_get_session(int channel, int *session)
812 #ifndef TIZEN_SMARTCARD_SUPPORT
813 return SMARTCARD_ERROR_NOT_SUPPORTED;
815 int ret = SMARTCARD_ERROR_NONE;
819 /* precondition check start */
823 cond_expr_ret(NULL == session, SMARTCARD_ERROR_INVALID_PARAMETER);
825 /* LCOV_EXCL_START */
826 ret = _check_precondition_channel(channel);
829 /* precondition check end */
831 ret = channel_get_session((channel_h)channel, session);
835 return _convert_error_code(__func__, ret);
840 int smartcard_channel_transmit(int channel, unsigned char *cmd, int cmd_len,
841 unsigned char **resp, int *length)
843 #ifndef TIZEN_SMARTCARD_SUPPORT
844 return SMARTCARD_ERROR_NOT_SUPPORTED;
846 int ret = SMARTCARD_ERROR_NONE;
850 /* precondition check start */
854 cond_expr_ret(NULL == resp, SMARTCARD_ERROR_INVALID_PARAMETER);
855 /* LCOV_EXCL_START */
856 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
858 ret = _check_precondition_channel(channel);
861 /* precondition check end */
863 ret = channel_transmit_sync((channel_h)channel, cmd, cmd_len, resp, (unsigned int *)length);
867 return _convert_error_code(__func__, ret);
872 int smartcard_channel_transmit_retrieve_response(int channel, unsigned char **resp, int *length)
874 #ifndef TIZEN_SMARTCARD_SUPPORT
875 return SMARTCARD_ERROR_NOT_SUPPORTED;
878 int ret = SMARTCARD_ERROR_NONE;
882 /* precondition check start */
886 cond_expr_ret(NULL == resp, SMARTCARD_ERROR_INVALID_PARAMETER);
887 /* LCOV_EXCL_START */
888 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
890 ret = _check_precondition_channel(channel);
893 /* precondition check end */
895 ret = channel_get_transmit_response((channel_h)channel, resp, &s_length);
896 *length = (int)s_length;
900 return _convert_error_code(__func__, ret);
905 int smartcard_channel_select_next(int channel, bool *is_success)
907 #ifndef TIZEN_SMARTCARD_SUPPORT
908 return SMARTCARD_ERROR_NOT_SUPPORTED;
910 int ret = SMARTCARD_ERROR_NONE;
914 /* precondition check start */
918 cond_expr_ret(NULL == is_success, SMARTCARD_ERROR_INVALID_PARAMETER);
920 /* LCOV_EXCL_START */
921 ret = _check_precondition_channel(channel);
924 /* precondition check end */
926 ret = channel_select_next((channel_h)channel, is_success);
930 return _convert_error_code(__func__, ret);