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_ENOUGH_RESOURCE:
191 case SCARD_ERROR_OUT_OF_MEMORY:
192 /* LCOV_EXCL_START */
193 error_code = SMARTCARD_ERROR_OUT_OF_MEMORY;
194 errorstr = "SMARTCARD_ERROR_OUT_OF_MEMORY";
197 case SCARD_ERROR_NOT_INITIALIZED:
198 case SCARD_ERROR_SE_NOT_INITIALIZED:
199 case SCARD_ERROR_OPERATION_NOT_SUPPORTED:
200 case SCARD_ERROR_NEED_MORE_BUFFER:
201 case SCARD_ERROR_OPERATION_TIMEOUT:
202 case SCARD_ERROR_UNKNOWN:
204 /* LCOV_EXCL_START */
205 error_code = SMARTCARD_ERROR_GENERAL;
206 errorstr = "SMARTCARD_ERROR_GENERAL";
210 _ERR("smartcard func : %s, %s(0x%08x)\n", func, errorstr, error_code);
216 /* managing apis : initaialize, deinitialize */
218 int smartcard_initialize(void)
220 #ifndef TIZEN_SMARTCARD_SUPPORT
221 return SMARTCARD_ERROR_NOT_SUPPORTED;
223 int ret = SMARTCARD_ERROR_NONE;
230 if (se_service == NULL || ref_count > 0) {
231 /* create se service instance. */
232 se_service = se_service_create_instance_sync(NULL, &ret);
233 if (se_service == NULL || ret != SCARD_ERROR_OK) {
234 SMARTCARD_UNLOCK; /* LCOV_EXCL_LINE */
235 if (ret == SCARD_ERROR_SECURITY_NOT_ALLOWED) /* LCOV_EXCL_LINE */
236 return SMARTCARD_ERROR_PERMISSION_DENIED;
238 return SMARTCARD_ERROR_GENERAL; /* LCOV_EXCL_LINE */
241 _is_initialize = true;
249 return _convert_error_code(__func__, ret);
253 int smartcard_deinitialize(void)
255 #ifndef TIZEN_SMARTCARD_SUPPORT
256 return SMARTCARD_ERROR_NOT_SUPPORTED;
258 int ret = SMARTCARD_ERROR_NONE;
269 return SMARTCARD_ERROR_NOT_INITIALIZED;
272 if (se_service != NULL && ref_count == 0) {
273 se_service_shutdown(se_service);
275 /* destroy se service instance. */
276 ret = se_service_destroy_instance(se_service);
277 if (ret != SCARD_ERROR_OK) {
278 /* LCOV_EXCL_START */
280 return SMARTCARD_ERROR_GENERAL;
285 g_list_free(reader_list);
286 g_list_free(session_list);
287 g_list_free(channel_list);
291 _is_initialize = false;
298 return _convert_error_code(__func__, ret);
303 /*----------------<SE Service mapping api>------------------*/
305 int smartcard_get_version(char **version)
307 #ifndef TIZEN_SMARTCARD_SUPPORT
308 return SMARTCARD_ERROR_NOT_SUPPORTED;
310 int ret = SMARTCARD_ERROR_NONE;
314 /* precondition check start */
318 cond_expr_ret(NULL == version, SMARTCARD_ERROR_INVALID_PARAMETER);
322 ret = se_service_get_version(se_service, version);
328 return _convert_error_code(__func__, ret);
332 int smartcard_get_readers(int **readers, int *length)
334 #ifndef TIZEN_SMARTCARD_SUPPORT
335 return SMARTCARD_ERROR_NOT_SUPPORTED;
338 int ret = SMARTCARD_ERROR_NONE;
342 /* precondition check start */
346 cond_expr_ret(NULL == readers, SMARTCARD_ERROR_INVALID_PARAMETER);
347 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
349 /* precondition check end */
353 ret = se_service_get_readers(se_service, readers, length);
357 for (i = 0; i < *length; i++) {
360 if (g_list_find(g_list_first(reader_list), GINT_TO_POINTER(*(readers[i]))) == NULL)
361 reader_list = g_list_append(reader_list, GINT_TO_POINTER(*(readers[i])));
368 return _convert_error_code(__func__, ret);
372 /*----------------<reader mapping api>------------------*/
374 int smartcard_reader_set_event_cb(smartcard_reader_event_cb cb, void *user_data)
376 #ifndef TIZEN_SMARTCARD_SUPPORT
377 return SMARTCARD_ERROR_NOT_SUPPORTED;
379 int ret = SMARTCARD_ERROR_NONE;
383 /* precondition check start */
388 cond_expr_ret(NULL == cb, SMARTCARD_ERROR_INVALID_PARAMETER);
390 /* precondition check end */
392 se_service_set_event_handler(se_service, (se_service_event_cb)cb, user_data);
396 return _convert_error_code(__func__, ret);
400 int smartcard_reader_unset_event_cb(void)
402 #ifndef TIZEN_SMARTCARD_SUPPORT
403 return SMARTCARD_ERROR_NOT_SUPPORTED;
405 int ret = SMARTCARD_ERROR_NONE;
409 /* precondition check start */
414 /* precondition check end */
416 se_service_unset_event_handler(se_service);
420 return _convert_error_code(__func__, ret);
424 int smartcard_reader_get_name(int reader, char **reader_name)
426 #ifndef TIZEN_SMARTCARD_SUPPORT
427 return SMARTCARD_ERROR_NOT_SUPPORTED;
429 int ret = SMARTCARD_ERROR_NONE;
433 /* precondition check start */
437 cond_expr_ret(NULL == reader_name, SMARTCARD_ERROR_INVALID_PARAMETER);
439 ret = _check_precondition_reader(reader);
442 /* precondition check end */
445 ret = reader_get_name((reader_h)reader, reader_name);
447 if (ret != SCARD_ERROR_OK || strlen(*reader_name) == 0)
448 return SMARTCARD_ERROR_GENERAL;
452 return SMARTCARD_ERROR_NONE;
456 int smartcard_reader_is_secure_element_present(int reader, bool *is_present)
458 #ifndef TIZEN_SMARTCARD_SUPPORT
459 return SMARTCARD_ERROR_NOT_SUPPORTED;
461 int ret = SMARTCARD_ERROR_NONE;
465 /* precondition check start */
469 cond_expr_ret(NULL == is_present, SMARTCARD_ERROR_INVALID_PARAMETER);
471 ret = _check_precondition_reader(reader);
474 /* precondition check end */
476 ret = reader_is_secure_element_present((reader_h)reader, is_present);
480 return _convert_error_code(__func__, ret);
484 int smartcard_reader_open_session(int reader, int *session)
486 #ifndef TIZEN_SMARTCARD_SUPPORT
487 return SMARTCARD_ERROR_NOT_SUPPORTED;
489 int ret = SMARTCARD_ERROR_NONE;
493 /* precondition check start */
497 ret = _check_precondition_reader(reader);
500 cond_expr_ret(NULL == session, SMARTCARD_ERROR_INVALID_PARAMETER);
502 /* precondition check end */
504 ret = reader_open_session_sync((reader_h)reader, session);
506 if (ret == SCARD_ERROR_OK) {
508 if (g_list_find(g_list_first(session_list), GINT_TO_POINTER(*session)) == NULL)
509 session_list = g_list_append(session_list, GINT_TO_POINTER(*session));
515 return _convert_error_code(__func__, ret);
519 int smartcard_reader_close_sessions(int reader)
521 #ifndef TIZEN_SMARTCARD_SUPPORT
522 return SMARTCARD_ERROR_NOT_SUPPORTED;
524 int ret = SMARTCARD_ERROR_NONE;
528 /* precondition check start */
532 ret = _check_precondition_reader(reader);
535 /* precondition check end */
537 ret = reader_close_sessions((reader_h)reader);
541 return _convert_error_code(__func__, ret);
545 /*----------------<session mapping api>------------------*/
547 int smartcard_session_get_reader(int session, int *reader)
549 #ifndef TIZEN_SMARTCARD_SUPPORT
550 return SMARTCARD_ERROR_NOT_SUPPORTED;
552 int ret = SMARTCARD_ERROR_NONE;
556 /* precondition check start */
560 cond_expr_ret(NULL == reader, SMARTCARD_ERROR_INVALID_PARAMETER);
562 ret = _check_precondition_session(session);
565 /* precondition check end */
567 ret = session_get_reader((session_h)session, reader);
571 return _convert_error_code(__func__, ret);
575 int smartcard_session_get_atr(int session, unsigned char **atr, int *length)
577 #ifndef TIZEN_SMARTCARD_SUPPORT
578 return SMARTCARD_ERROR_NOT_SUPPORTED;
580 int ret = SMARTCARD_ERROR_NONE;
584 /* precondition check start */
588 cond_expr_ret(NULL == atr, SMARTCARD_ERROR_INVALID_PARAMETER);
589 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
591 ret = _check_precondition_session(session);
597 /* precondition check end */
598 ret = session_get_atr_sync((session_h)session, atr, (unsigned int *)length);
600 if (ret == SCARD_ERROR_OK) {
601 if (((*atr == NULL) && (*length != 0)) ||
602 ((*atr != NULL) && (*length == 0))) {
603 return SMARTCARD_ERROR_GENERAL;
609 return _convert_error_code(__func__, ret);
613 int smartcard_session_close(int session)
615 #ifndef TIZEN_SMARTCARD_SUPPORT
616 return SMARTCARD_ERROR_NOT_SUPPORTED;
618 int ret = SMARTCARD_ERROR_NONE;
622 /* precondition check start */
626 ret = _check_precondition_session(session);
629 /* precondition check end */
631 ret = session_close_sync((session_h)session);
635 return _convert_error_code(__func__, ret);
639 int smartcard_session_is_closed(int session, bool *is_closed)
641 #ifndef TIZEN_SMARTCARD_SUPPORT
642 return SMARTCARD_ERROR_NOT_SUPPORTED;
644 int ret = SMARTCARD_ERROR_NONE;
648 /* precondition check start */
652 cond_expr_ret(NULL == is_closed, SMARTCARD_ERROR_INVALID_PARAMETER);
654 ret = _check_precondition_session(session);
657 /* precondition check end */
659 ret = session_is_closed((session_h)session, is_closed);
663 return _convert_error_code(__func__, ret);
667 int smartcard_session_close_channels(int session)
669 #ifndef TIZEN_SMARTCARD_SUPPORT
670 return SMARTCARD_ERROR_NOT_SUPPORTED;
672 int ret = SMARTCARD_ERROR_NONE;
676 /* precondition check start */
680 ret = _check_precondition_session(session);
683 /* precondition check end */
685 ret = session_close_channels((session_h)session);
689 return _convert_error_code(__func__, ret);
693 int smartcard_session_open_basic_channel(int session, unsigned char *aid, int aid_len,
694 unsigned char P2, int *channel)
696 #ifndef TIZEN_SMARTCARD_SUPPORT
697 return SMARTCARD_ERROR_NOT_SUPPORTED;
699 int ret = SMARTCARD_ERROR_NONE;
703 /* precondition check start */
707 cond_expr_ret(NULL == channel, SMARTCARD_ERROR_INVALID_PARAMETER);
709 /* LCOV_EXCL_START */
710 ret = _check_precondition_session(session);
713 /* precondition check end */
715 ret = session_open_basic_channel_sync((session_h)session, aid, aid_len, P2, channel);
717 if (ret == SCARD_ERROR_OK) {
719 if (g_list_find(g_list_first(channel_list), GINT_TO_POINTER(*channel)) == NULL)
720 channel_list = g_list_append(channel_list, GINT_TO_POINTER(*channel));
726 return _convert_error_code(__func__, ret);
731 int smartcard_session_open_logical_channel(int session, unsigned char *aid, int aid_len,
732 unsigned char P2, int *channel)
734 #ifndef TIZEN_SMARTCARD_SUPPORT
735 return SMARTCARD_ERROR_NOT_SUPPORTED;
737 int ret = SMARTCARD_ERROR_NONE;
741 /* precondition check start */
745 cond_expr_ret(NULL == channel, SMARTCARD_ERROR_INVALID_PARAMETER);
747 /* LCOV_EXCL_START */
748 ret = _check_precondition_session(session);
751 /* precondition check end */
753 ret = session_open_logical_channel_sync((session_h)session, aid, aid_len, P2, channel);
755 if (ret == SCARD_ERROR_OK) {
757 if (g_list_find(g_list_first(channel_list), GINT_TO_POINTER(*channel)) == NULL)
758 channel_list = g_list_append(channel_list, GINT_TO_POINTER(*channel));
764 return _convert_error_code(__func__, ret);
769 /*----------------<channel mapping api>------------------*/
771 int smartcard_channel_close(int channel)
773 #ifndef TIZEN_SMARTCARD_SUPPORT
774 return SMARTCARD_ERROR_NOT_SUPPORTED;
776 int ret = SMARTCARD_ERROR_NONE;
780 /* precondition check start */
784 ret = _check_precondition_channel(channel);
787 /* precondition check end */
788 /* LCOV_EXCL_START */
789 ret = channel_close_sync((channel_h)channel);
793 return _convert_error_code(__func__, ret);
798 int smartcard_channel_is_basic_channel(int channel, bool *is_basic_channel)
800 #ifndef TIZEN_SMARTCARD_SUPPORT
801 return SMARTCARD_ERROR_NOT_SUPPORTED;
803 int ret = SMARTCARD_ERROR_NONE;
807 /* precondition check start */
811 cond_expr_ret(NULL == is_basic_channel, SMARTCARD_ERROR_INVALID_PARAMETER);
813 /* LCOV_EXCL_START */
814 ret = _check_precondition_channel(channel);
817 /* precondition check end */
819 ret = channel_is_basic_channel((channel_h)channel, is_basic_channel);
823 return _convert_error_code(__func__, ret);
828 int smartcard_channel_is_closed(int channel, bool *is_closed)
830 #ifndef TIZEN_SMARTCARD_SUPPORT
831 return SMARTCARD_ERROR_NOT_SUPPORTED;
833 int ret = SMARTCARD_ERROR_NONE;
837 /* precondition check start */
841 cond_expr_ret(NULL == is_closed, SMARTCARD_ERROR_INVALID_PARAMETER);
843 /* LCOV_EXCL_START */
844 ret = _check_precondition_channel(channel);
847 /* precondition check end */
849 ret = channel_is_closed((channel_h)channel, is_closed);
853 return _convert_error_code(__func__, ret);
858 int smartcard_channel_get_select_response(int channel, unsigned char **select_resp,
861 #ifndef TIZEN_SMARTCARD_SUPPORT
862 return SMARTCARD_ERROR_NOT_SUPPORTED;
865 int ret = SMARTCARD_ERROR_NONE;
869 /* precondition check start */
873 cond_expr_ret(NULL == select_resp, SMARTCARD_ERROR_INVALID_PARAMETER);
874 /* LCOV_EXCL_START */
875 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
877 ret = _check_precondition_channel(channel);
880 /* precondition check end */
882 ret = channel_get_select_response((channel_h)channel, select_resp, &s_length);
883 *length = (int)s_length;
887 return _convert_error_code(__func__, ret);
892 int smartcard_channel_get_session(int channel, int *session)
894 #ifndef TIZEN_SMARTCARD_SUPPORT
895 return SMARTCARD_ERROR_NOT_SUPPORTED;
897 int ret = SMARTCARD_ERROR_NONE;
901 /* precondition check start */
905 cond_expr_ret(NULL == session, SMARTCARD_ERROR_INVALID_PARAMETER);
907 /* LCOV_EXCL_START */
908 ret = _check_precondition_channel(channel);
911 /* precondition check end */
913 ret = channel_get_session((channel_h)channel, session);
917 return _convert_error_code(__func__, ret);
922 int smartcard_channel_transmit(int channel, unsigned char *cmd, int cmd_len,
923 unsigned char **resp, int *length)
925 #ifndef TIZEN_SMARTCARD_SUPPORT
926 return SMARTCARD_ERROR_NOT_SUPPORTED;
928 int ret = SMARTCARD_ERROR_NONE;
932 /* precondition check start */
936 cond_expr_ret(NULL == resp, SMARTCARD_ERROR_INVALID_PARAMETER);
937 /* LCOV_EXCL_START */
938 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
940 ret = _check_precondition_channel(channel);
943 /* precondition check end */
945 ret = channel_transmit_sync((channel_h)channel, cmd, cmd_len, resp, (unsigned int *)length);
949 return _convert_error_code(__func__, ret);
954 int smartcard_channel_transmit_retrieve_response(int channel, unsigned char **resp, int *length)
956 #ifndef TIZEN_SMARTCARD_SUPPORT
957 return SMARTCARD_ERROR_NOT_SUPPORTED;
960 int ret = SMARTCARD_ERROR_NONE;
964 /* precondition check start */
968 cond_expr_ret(NULL == resp, SMARTCARD_ERROR_INVALID_PARAMETER);
969 /* LCOV_EXCL_START */
970 cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER);
972 ret = _check_precondition_channel(channel);
975 /* precondition check end */
977 ret = channel_get_transmit_response((channel_h)channel, resp, &s_length);
978 *length = (int)s_length;
982 return _convert_error_code(__func__, ret);
987 int smartcard_channel_select_next(int channel, bool *is_success)
989 #ifndef TIZEN_SMARTCARD_SUPPORT
990 return SMARTCARD_ERROR_NOT_SUPPORTED;
992 int ret = SMARTCARD_ERROR_NONE;
996 /* precondition check start */
1000 cond_expr_ret(NULL == is_success, SMARTCARD_ERROR_INVALID_PARAMETER);
1002 /* LCOV_EXCL_START */
1003 ret = _check_precondition_channel(channel);
1006 /* precondition check end */
1008 ret = channel_select_next((channel_h)channel, is_success);
1012 return _convert_error_code(__func__, ret);
1013 /* LCOV_EXCL_STOP */