From 96f47f2d52db3701710b701a88c1b63a82301c97 Mon Sep 17 00:00:00 2001 From: estkme <145633413+estkme@users.noreply.github.com> Date: Wed, 20 Mar 2024 13:51:58 +0800 Subject: [PATCH] [WIP] remove dlfcn interface driver (curl on Windows still require dlfcn) --- CMakeLists.txt | 21 +- README.md | 1 - euicc/interface.h | 6 - interface/CMakeLists.txt | 2 - interface/LICENSE | 21 -- interface/http/curl.c | 188 ---------------- src/CMakeLists.txt | 11 +- src/dlsym_interface.c | 144 ------------ src/dlsym_interface.h | 9 - src/driver.c | 126 +++++++++++ src/driver.h | 27 +++ {interface => src/driver}/apdu/CMakeLists.txt | 2 +- {interface => src/driver}/apdu/at.c | 81 ++----- src/driver/apdu/at.h | 4 + {interface => src/driver}/apdu/gbinder_hidl.c | 18 +- src/driver/apdu/gbinder_hidl.h | 4 + {interface => src/driver}/apdu/pcsc.c | 26 ++- src/driver/apdu/pcsc.h | 4 + {interface => src/driver}/apdu/stdio.c | 109 ++-------- src/driver/apdu/stdio.h | 4 + {interface => src/driver}/http/CMakeLists.txt | 0 src/driver/http/curl.c | 205 ++++++++++++++++++ src/driver/http/curl.h | 4 + {interface => src/driver}/http/stdio.c | 109 ++-------- src/driver/http/stdio.h | 4 + src/main.c | 13 +- 26 files changed, 499 insertions(+), 644 deletions(-) delete mode 100644 interface/CMakeLists.txt delete mode 100644 interface/LICENSE delete mode 100644 interface/http/curl.c delete mode 100644 src/dlsym_interface.c delete mode 100644 src/dlsym_interface.h create mode 100644 src/driver.c create mode 100644 src/driver.h rename {interface => src/driver}/apdu/CMakeLists.txt (99%) rename {interface => src/driver}/apdu/at.c (76%) create mode 100644 src/driver/apdu/at.h rename {interface => src/driver}/apdu/gbinder_hidl.c (96%) create mode 100644 src/driver/apdu/gbinder_hidl.h rename {interface => src/driver}/apdu/pcsc.c (95%) create mode 100644 src/driver/apdu/pcsc.h rename {interface => src/driver}/apdu/stdio.c (77%) create mode 100644 src/driver/apdu/stdio.h rename {interface => src/driver}/http/CMakeLists.txt (100%) create mode 100644 src/driver/http/curl.c create mode 100644 src/driver/http/curl.h rename {interface => src/driver}/http/stdio.c (70%) create mode 100644 src/driver/http/stdio.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5105af7..40ae580 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required (VERSION 3.8) + project (lpac VERSION 1.0.1 HOMEPAGE_URL "https://github.com/estkme-group/lpac" @@ -13,10 +14,6 @@ if (APPLE) set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") endif() -if(CYGWIN) - add_definitions(-DHAVE_TIMEGM=1) -endif() - if(UNIX) include(GNUInstallDirs) if(NOT CMAKE_INSTALL_RPATH) @@ -24,6 +21,13 @@ if(UNIX) endif() endif() +if(WIN32) + add_subdirectory(dlfcn-win32) + set(DL_LIBRARY dlfcn-win32) +else() + set(DL_LIBRARY dl) +endif() + if(CPACK_GENERATOR) set(CPACK_PACKAGE_VENDOR "eSTK.me Group") @@ -31,20 +35,13 @@ if(CPACK_GENERATOR) set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc") set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "libcurl, libpcsclite, pcscd") - set(CPACK_RPM_PACKAGE_LICENSE "AGPL-3.0-only AND LGPL-2.0-only AND MIT") + set(CPACK_RPM_PACKAGE_LICENSE "AGPL-3.0-only AND LGPL-2.0-only") set(CPACK_RPM_PACKAGE_AUTOREQ "yes") set(CPACK_RPM_PACKAGE_REQUIRES "libcurl, libpcsclite, pcscd") include(CPack) endif() -if(MINGW) - add_subdirectory(dlfcn-win32) - set(DL_LIBRARY dlfcn-win32) -else() - set(DL_LIBRARY dl) -endif() add_subdirectory(cjson) add_subdirectory(euicc) -add_subdirectory(interface) add_subdirectory(src) diff --git a/README.md b/README.md index e6b2a7d..6a3e819 100644 --- a/README.md +++ b/README.md @@ -489,6 +489,5 @@ A: The verification of SM-DP+ servers of telecom operators is diverse. Please ch - lpac (/src): AGPL-3.0 - libeuicc (/euicc): LGPL-v2 -- interfaces (/interface): MIT Copyright (c) 2023-2024 eSTKme Group diff --git a/euicc/interface.h b/euicc/interface.h index ccb4d52..5bb8574 100644 --- a/euicc/interface.h +++ b/euicc/interface.h @@ -1,12 +1,6 @@ #pragma once #include -#ifdef __MINGW32__ -#define EUICC_SHARED_EXPORT __declspec(dllexport) __cdecl -#else -#define EUICC_SHARED_EXPORT -#endif - struct euicc_ctx; struct euicc_apdu_interface diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt deleted file mode 100644 index 7f41153..0000000 --- a/interface/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_subdirectory(apdu) -add_subdirectory(http) diff --git a/interface/LICENSE b/interface/LICENSE deleted file mode 100644 index f4b867f..0000000 --- a/interface/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 estkme-group - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/interface/http/curl.c b/interface/http/curl.c deleted file mode 100644 index 66bef0c..0000000 --- a/interface/http/curl.c +++ /dev/null @@ -1,188 +0,0 @@ -#include -#include -#include -#include - -#ifdef __MINGW32__ -#include -#else -#include -#endif - -#include - -/* BEGIN MINIMAL CURL DEFINE */ -#if defined (_WIN32) || defined (__CYGWIN__) -#define LIBCURL_DEFAULT_PATH "libcurl.dll" -#elif defined(__APPLE__) -#define LIBCURL_DEFAULT_PATH "libcurl.4.dylib" -#else -#define LIBCURL_DEFAULT_PATH "libcurl.so.4" -#endif - -#define CURL_GLOBAL_DEFAULT ((1 << 0) | (1 << 1)) -#define CURLE_OK 0 -#define CURLOPT_URL 10002 -#define CURLOPT_WRITEFUNCTION 20011 -#define CURLOPT_WRITEDATA 10001 -#define CURLOPT_SSL_VERIFYPEER 64 -#define CURLOPT_SSL_VERIFYHOST 81 -#define CURLOPT_HTTPHEADER 10023 -#define CURLOPT_POSTFIELDS 10015 -#define CURLOPT_POSTFIELDSIZE 60 -#define CURLINFO_RESPONSE_CODE 2097154 - -typedef void CURL; -typedef int CURLcode; -typedef int CURLoption; -typedef int CURLINFO; - -static void *libcurl_interface_dlhandle = NULL; - -static struct libcurl_interface -{ - CURLcode (*curl_global_init)(long flags); - CURL *(*curl_easy_init)(void); - CURLcode (*curl_easy_setopt)(CURL *curl, CURLoption option, ...); - CURLcode (*curl_easy_perform)(CURL *curl); - CURLcode (*curl_easy_getinfo)(CURL *curl, CURLINFO info, ...); - const char *(*curl_easy_strerror)(CURLcode); - void (*curl_easy_cleanup)(CURL *curl); - - struct curl_slist *(*curl_slist_append)(struct curl_slist *list, const char *data); - void (*curl_slist_free_all)(struct curl_slist *list); -} libcurl; -/* END MINIMAL CURL DEFINE */ - -struct http_trans_response_data -{ - uint8_t *data; - size_t size; -}; - -static size_t http_trans_write_callback(void *contents, size_t size, size_t nmemb, void *userp) -{ - size_t realsize = size * nmemb; - struct http_trans_response_data *mem = (struct http_trans_response_data *)userp; - - mem->data = realloc(mem->data, mem->size + realsize + 1); - if (mem->data == NULL) - { - /* out of memory! */ - printf("not enough memory (realloc returned NULL)\n"); - return 0; - } - - memcpy(&(mem->data[mem->size]), contents, realsize); - mem->size += realsize; - mem->data[mem->size] = 0; - - return realsize; -} - -static int http_interface_transmit(struct euicc_ctx *ctx, const char *url, uint32_t *rcode, uint8_t **rx, uint32_t *rx_len, const uint8_t *tx, uint32_t tx_len, const char **h) -{ - int fret = 0; - CURL *curl; - CURLcode res; - struct http_trans_response_data responseData = {0}; - struct curl_slist *headers = NULL, *nheaders = NULL; - long response_code; - - (*rx) = NULL; - (*rcode) = 0; - - curl = libcurl.curl_easy_init(); - if (!curl) - { - goto err; - } - - libcurl.curl_easy_setopt(curl, CURLOPT_URL, url); - libcurl.curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_trans_write_callback); - libcurl.curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&responseData); - libcurl.curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - libcurl.curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); - for (int i = 0; h[i] != NULL; i++) - { - nheaders = libcurl.curl_slist_append(headers, h[i]); - if (nheaders == NULL) - { - goto err; - } - headers = nheaders; - } - libcurl.curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - - if (tx != NULL) - { - libcurl.curl_easy_setopt(curl, CURLOPT_POSTFIELDS, tx); - libcurl.curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, tx_len); - } - - res = libcurl.curl_easy_perform(curl); - - if (res != CURLE_OK) - { - fprintf(stderr, "curl_easy_perform() failed: %s\n", libcurl.curl_easy_strerror(res)); - goto err; - } - - libcurl.curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); - *rcode = response_code; - *rx = responseData.data; - *rx_len = responseData.size; - - fret = 0; - goto exit; - -err: - fret = -1; - free(responseData.data); -exit: - libcurl.curl_easy_cleanup(curl); - libcurl.curl_slist_free_all(headers); - return fret; -} - -EUICC_SHARED_EXPORT int libhttpinterface_init(struct euicc_http_interface *ifstruct) -{ - const char *libcurl_path; - - memset(ifstruct, 0, sizeof(struct euicc_http_interface)); - - if (!(libcurl_path = getenv("LIBCURL"))) - { - libcurl_path = LIBCURL_DEFAULT_PATH; - } - - if (!(libcurl_interface_dlhandle = dlopen(libcurl_path, RTLD_LAZY))) - { - fprintf(stderr, "libcurl env missing, current: LIBCURL=%s err:%s\n", libcurl_path, dlerror()); - return -1; - } - - libcurl.curl_global_init = dlsym(libcurl_interface_dlhandle, "curl_global_init"); - libcurl.curl_easy_init = dlsym(libcurl_interface_dlhandle, "curl_easy_init"); - libcurl.curl_easy_setopt = dlsym(libcurl_interface_dlhandle, "curl_easy_setopt"); - libcurl.curl_easy_perform = dlsym(libcurl_interface_dlhandle, "curl_easy_perform"); - libcurl.curl_easy_getinfo = dlsym(libcurl_interface_dlhandle, "curl_easy_getinfo"); - libcurl.curl_easy_strerror = dlsym(libcurl_interface_dlhandle, "curl_easy_strerror"); - libcurl.curl_easy_cleanup = dlsym(libcurl_interface_dlhandle, "curl_easy_cleanup"); - libcurl.curl_slist_append = dlsym(libcurl_interface_dlhandle, "curl_slist_append"); - libcurl.curl_slist_free_all = dlsym(libcurl_interface_dlhandle, "curl_slist_free_all"); - - if (libcurl.curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) - { - return -1; - } - - ifstruct->transmit = http_interface_transmit; - - return 0; -} - -EUICC_SHARED_EXPORT int libhttpinterface_main(int argc, char **argv) -{ - return 0; -} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f93bfad..4bdb7b0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,16 +5,25 @@ else() endif() aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} DIR_LPAC_SRCS) + aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/applet DIR_LPAC_SRCS) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/applet/chip DIR_LPAC_SRCS) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/applet/notification DIR_LPAC_SRCS) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/applet/profile DIR_LPAC_SRCS) + +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/driver DIR_LPAC_SRCS) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/driver/apdu DIR_LPAC_SRCS) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/driver/http DIR_LPAC_SRCS) + +find_package(PCSCLite) +find_package(curl) + add_executable(lpac ${DIR_LPAC_SRCS}) set_target_properties(lpac PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/output" BUILD_RPATH "${RPATH_BINARY_PATH}" ) -target_link_libraries(lpac euicc ${DL_LIBRARY}) +target_link_libraries(lpac euicc PCSCLite::PCSCLite curl ${DL_LIBRARY}) target_include_directories(lpac PUBLIC $) find_package(Git) diff --git a/src/dlsym_interface.c b/src/dlsym_interface.c deleted file mode 100644 index 03464d0..0000000 --- a/src/dlsym_interface.c +++ /dev/null @@ -1,144 +0,0 @@ -#include "dlsym_interface.h" -#include -#include -#include -#include - -#ifdef __MINGW32__ -#include -#else -#include -#endif - -#if defined (_WIN32) || defined (__CYGWIN__) -#define INTERFACELIB_EXTENSION "dll" -#elif defined(__APPLE__) -#define INTERFACELIB_EXTENSION "dylib" -#else -#define INTERFACELIB_EXTENSION "so" -#endif - -static struct applet_entry applet_apdu = { - .name = "apdu", - .main = NULL, -}; - -static struct applet_entry applet_http = { - .name = "http", - .main = NULL, -}; - -static const struct applet_entry *applets[] = { - &applet_apdu, - &applet_http, - NULL, -}; - -static const char *libapduinterface_path = NULL; -static void *apdu_interface_dlhandle = NULL; -struct euicc_apdu_interface dlsym_apdu_interface = {0}; -static int (*libapduinterface_init)(struct euicc_apdu_interface *ifstruct) = NULL; -static int (*libapduinterface_main)(int argc, char **argv) = NULL; - -static const char *libhttpinterface_path = NULL; -static void *http_interface_dlhandle = NULL; -struct euicc_http_interface dlsym_http_interface = {0}; -static int (*libhttpinterface_init)(struct euicc_http_interface *ifstruct) = NULL; -static int (*libhttpinterface_main)(int argc, char **argv) = NULL; - -static void dlsym_interfaces_get_path(void) -{ - if (!(libapduinterface_path = getenv("APDU_INTERFACE"))) - { - libapduinterface_path = "libapduinterface_pcsc." INTERFACELIB_EXTENSION; - } - - if (!(libhttpinterface_path = getenv("HTTP_INTERFACE"))) - { - libhttpinterface_path = "libhttpinterface_curl." INTERFACELIB_EXTENSION; - } -} - -static int dlsym_interface_get_dlhandle(void) -{ - if (!(apdu_interface_dlhandle = dlopen(libapduinterface_path, RTLD_LAZY))) - { - apdu_interface_dlhandle = NULL; - fprintf(stderr, "APDU interface env missing, current: APDU_INTERFACE=%s err:%s\n", libapduinterface_path, dlerror()); - return -1; - } - - if (!(http_interface_dlhandle = dlopen(libhttpinterface_path, RTLD_LAZY))) - { - http_interface_dlhandle = NULL; - fprintf(stderr, "HTTP interface env missing, current: HTTP_INTERFACE=%s err:%s\n", libhttpinterface_path, dlerror()); - } - - return 0; -} - -int dlsym_interface_init() -{ - dlsym_interfaces_get_path(); - - if (dlsym_interface_get_dlhandle()) - { - return -1; - } - - if (apdu_interface_dlhandle) - { - libapduinterface_init = dlsym(apdu_interface_dlhandle, "libapduinterface_init"); - if (!libapduinterface_init) - { - fprintf(stderr, "APDU library broken: missing libapduinterface_init\n"); - return -1; - } - if (libapduinterface_init(&dlsym_apdu_interface) < 0) - { - fprintf(stderr, "APDU library init error\n"); - return -1; - } - libapduinterface_main = dlsym(apdu_interface_dlhandle, "libapduinterface_main"); - if (!libapduinterface_main) - { - fprintf(stderr, "APDU library broken: missing libapduinterface_main\n"); - return -1; - } - applet_apdu.main = libapduinterface_main; - } - - if (http_interface_dlhandle) - { - libhttpinterface_init = dlsym(http_interface_dlhandle, "libhttpinterface_init"); - if (!libhttpinterface_init) - { - fprintf(stderr, "HTTP library broken: missing libhttpinterface_init\n"); - return -1; - } - if (libhttpinterface_init(&dlsym_http_interface) < 0) - { - fprintf(stderr, "HTTP library init error\n"); - return -1; - } - libhttpinterface_main = dlsym(http_interface_dlhandle, "libhttpinterface_main"); - if (!libhttpinterface_main) - { - fprintf(stderr, "HTTP library broken: missing libhttpinterface_main\n"); - return -1; - } - applet_http.main = libhttpinterface_main; - } - - return 0; -} - -static int dlsym_interface_applet_main(int argc, char **argv) -{ - return applet_entry(argc, argv, applets); -} - -struct applet_entry applet_dlsym_interface = { - .name = "driver", - .main = dlsym_interface_applet_main, -}; diff --git a/src/dlsym_interface.h b/src/dlsym_interface.h deleted file mode 100644 index f6f7049..0000000 --- a/src/dlsym_interface.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include -#include - -extern struct euicc_apdu_interface dlsym_apdu_interface; -extern struct euicc_http_interface dlsym_http_interface; -extern struct applet_entry applet_dlsym_interface; - -int dlsym_interface_init(void); diff --git a/src/driver.c b/src/driver.c new file mode 100644 index 0000000..2d7f524 --- /dev/null +++ b/src/driver.c @@ -0,0 +1,126 @@ +#include "driver.h" + +#include +#include +#include + +#ifdef LPAC_WITH_APDU_GBINDER_HIDL +#include "driver/apdu/gbinder_hidl.h" +#endif + +#ifndef LPAC_WITHOUT_APDU_PCSC +#include "driver/apdu/pcsc.h" +#endif +#ifndef LPAC_WITHOUT_APDU_AT +#include "driver/apdu/at.h" +#endif +#ifndef LPAC_WITHOUT_HTTP_CURL +#include "driver/http/curl.h" +#endif +#include "driver/apdu/stdio.h" +#include "driver/http/stdio.h" + +static const struct lpac_driver *drivers[] = { +#ifdef LPAC_WITH_APDU_GBINDER_HIDL + &driver_apdu_gbinder_hidl, +#endif +#ifndef LPAC_WITHOUT_APDU_PCSC + &driver_apdu_pcsc, +#endif +#ifndef LPAC_WITHOUT_APDU_AT + &driver_apdu_at, +#endif +#ifndef LPAC_WITHOUT_HTTP_CURL + &driver_http_curl, +#endif + &driver_apdu_stdio, + &driver_http_stdio, + NULL, +}; + +struct euicc_apdu_interface driver_interface_apdu; +struct euicc_http_interface driver_interface_http; +static struct applet_entry applet_apdu = { + .name = "apdu", + .main = NULL, +}; +static struct applet_entry applet_http = { + .name = "http", + .main = NULL, +}; + +static const struct lpac_driver *_driver_apdu = NULL; +static const struct lpac_driver *_driver_http = NULL; + +static const struct lpac_driver *_find_driver(enum lpac_driver_type type, const char *name) +{ + for (int i = 0; drivers[i] != NULL; i++) + { + const struct lpac_driver *d = drivers[i]; + if (d->type != type) + { + continue; + } + if (name == NULL) + { + return d; + } + if (strcmp(d->name, name) == 0) + { + return d; + } + } + return NULL; +} + +int driver_init() +{ + _driver_apdu = _find_driver(DRIVER_APDU, getenv("LPAC_APDU")); + if (_driver_apdu == NULL) + { + fprintf(stderr, "No APDU driver found\n"); + return -1; + } + + _driver_http = _find_driver(DRIVER_HTTP, getenv("LPAC_HTTP")); + if (_driver_http == NULL) + { + fprintf(stderr, "No HTTP driver found\n"); + return -1; + } + + _driver_apdu->init(&driver_interface_apdu); + _driver_http->init(&driver_interface_http); + + applet_apdu.main = _driver_apdu->main; + applet_http.main = _driver_http->main; + + return 0; +} + +void driver_fini() +{ + if (_driver_apdu != NULL) + { + _driver_apdu->fini(); + } + if (_driver_http != NULL) + { + _driver_http->fini(); + } +} + +static int dlsym_interface_applet_main(int argc, char **argv) +{ + static const struct applet_entry *applets[] = { + &applet_apdu, + &applet_http, + NULL, + }; + return applet_entry(argc, argv, applets); +} + +struct applet_entry driver_applet = { + .name = "driver", + .main = dlsym_interface_applet_main, +}; diff --git a/src/driver.h b/src/driver.h new file mode 100644 index 0000000..1d95d81 --- /dev/null +++ b/src/driver.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include +#include +#include + +enum lpac_driver_type +{ + DRIVER_APDU, + DRIVER_HTTP, +}; + +struct lpac_driver +{ + enum lpac_driver_type type; + const char *name; + int (*init)(void *interface); + int (*main)(int argc, char **argv); + void (*fini)(void); +}; + +extern struct euicc_apdu_interface driver_interface_apdu; +extern struct euicc_http_interface driver_interface_http; +extern struct applet_entry driver_applet; + +int driver_init(void); +void driver_fini(void); diff --git a/interface/apdu/CMakeLists.txt b/src/driver/apdu/CMakeLists.txt similarity index 99% rename from interface/apdu/CMakeLists.txt rename to src/driver/apdu/CMakeLists.txt index 9c8f2f7..805893c 100644 --- a/interface/apdu/CMakeLists.txt +++ b/src/driver/apdu/CMakeLists.txt @@ -10,7 +10,7 @@ if(LPAC_APDU_INTERFACE_PCSC) install(TARGETS apduinterface_pcsc LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/lpac") endif() - if(MINGW OR CYGWIN) + if(WIN32) target_link_libraries(apduinterface_pcsc winscard) elseif(APPLE) target_link_libraries(apduinterface_pcsc "-framework PCSC") diff --git a/interface/apdu/at.c b/src/driver/apdu/at.c similarity index 76% rename from interface/apdu/at.c rename to src/driver/apdu/at.c index a5c7ec8..2594cfe 100644 --- a/interface/apdu/at.c +++ b/src/driver/apdu/at.c @@ -1,3 +1,5 @@ +#include "at.h" + #include #include #include @@ -5,70 +7,11 @@ #include #include +#include static FILE *fuart; static int logic_channel = 0; -static int hexutil_hex2bin(uint8_t *output, uint32_t output_len, const char *str, uint32_t str_len) -{ - uint32_t length; - - if (!str || !output || str_len % 2 != 0) - { - return -1; - } - - length = str_len / 2; - if (length > output_len) - { - return -1; - } - - for (uint32_t i = 0; i < length; ++i) - { - char high = str[2 * i]; - char low = str[2 * i + 1]; - - if (high >= '0' && high <= '9') - { - high -= '0'; - } - else if (high >= 'a' && high <= 'f') - { - high = high - 'a' + 10; - } - else if (high >= 'A' && high <= 'F') - { - high = high - 'A' + 10; - } - else - { - return -1; - } - - if (low >= '0' && low <= '9') - { - low -= '0'; - } - else if (low >= 'a' && low <= 'f') - { - low = low - 'a' + 10; - } - else if (low >= 'A' && low <= 'F') - { - low = low - 'A' + 10; - } - else - { - return -1; - } - - output[i] = (high << 4) + low; - } - - return length; -} - static int at_expect(char **response, const char *expected) { char buffer[1024]; @@ -195,7 +138,7 @@ static int apdu_interface_transmit(struct euicc_ctx *ctx, uint8_t **rx, uint32_t goto err; } - ret = hexutil_hex2bin(*rx, *rx_len, hexstr, strlen(hexstr)); + ret = euicc_hexutil_hex2bin_r(*rx, *rx_len, hexstr, strlen(hexstr)); if (ret < 0) { goto err; @@ -257,7 +200,7 @@ static void apdu_interface_logic_channel_close(struct euicc_ctx *ctx, uint8_t ch at_expect(NULL, NULL); } -int libapduinterface_init(struct euicc_apdu_interface *ifstruct) +static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) { memset(ifstruct, 0, sizeof(struct euicc_apdu_interface)); @@ -270,7 +213,19 @@ int libapduinterface_init(struct euicc_apdu_interface *ifstruct) return 0; } -int libapduinterface_main(int argc, char **argv) +static int libapduinterface_main(int argc, char **argv) { return 0; } + +static void libapduinterface_fini(void) +{ +} + +const struct lpac_driver driver_apdu_at = { + .type = DRIVER_APDU, + .name = "at", + .init = (int (*)(void *))libapduinterface_init, + .main = libapduinterface_main, + .fini = libapduinterface_fini, +}; diff --git a/src/driver/apdu/at.h b/src/driver/apdu/at.h new file mode 100644 index 0000000..70d6d40 --- /dev/null +++ b/src/driver/apdu/at.h @@ -0,0 +1,4 @@ +#pragma once +#include + +extern const struct lpac_driver driver_apdu_at; diff --git a/interface/apdu/gbinder_hidl.c b/src/driver/apdu/gbinder_hidl.c similarity index 96% rename from interface/apdu/gbinder_hidl.c rename to src/driver/apdu/gbinder_hidl.c index dbf0b7f..9748def 100644 --- a/interface/apdu/gbinder_hidl.c +++ b/src/driver/apdu/gbinder_hidl.c @@ -1,4 +1,6 @@ // vim: expandtab sw=4 ts=4: +#include "gbinder_hidl.h" + #include #include #include @@ -289,7 +291,7 @@ static int apdu_interface_transmit(struct euicc_ctx *ctx, uint8_t **rx, uint32_t return 0; } -EUICC_SHARED_EXPORT int libapduinterface_init(struct euicc_apdu_interface *ifstruct) +static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) { ifstruct->connect = apdu_interface_connect; ifstruct->disconnect = apdu_interface_disconnect; @@ -307,7 +309,19 @@ EUICC_SHARED_EXPORT int libapduinterface_init(struct euicc_apdu_interface *ifstr return 0; } -EUICC_SHARED_EXPORT int libapduinterface_main(int argc, char **argv) +static int libapduinterface_main(int argc, char **argv) { return 0; } + +static void libapduinterface_fini(void) +{ +} + +const struct lpac_driver driver_apdu_gbinder_hidl = { + .type = DRIVER_APDU, + .name = "gbinder_hidl", + .init = libapduinterface_init, + .main = libapduinterface_main, + .fini = libapduinterface_fini, +}; diff --git a/src/driver/apdu/gbinder_hidl.h b/src/driver/apdu/gbinder_hidl.h new file mode 100644 index 0000000..113404f --- /dev/null +++ b/src/driver/apdu/gbinder_hidl.h @@ -0,0 +1,4 @@ +#pragma once +#include + +extern const struct lpac_driver driver_apdu_gbinder_hidl; diff --git a/interface/apdu/pcsc.c b/src/driver/apdu/pcsc.c similarity index 95% rename from interface/apdu/pcsc.c rename to src/driver/apdu/pcsc.c index 6b8d71d..b78e979 100644 --- a/interface/apdu/pcsc.c +++ b/src/driver/apdu/pcsc.c @@ -1,21 +1,19 @@ +#include "pcsc.h" + #include #include #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include -#elif defined(__CYGWIN__) -#include "/usr/include/w32api/winscard.h" -#include "/usr/include/w32api/wtypes.h" #else #include #include #endif -#include - #include +#include #define INTERFACE_SELECT_ENV "DRIVER_IFID" @@ -392,7 +390,7 @@ static int pcsc_list_iter(int index, const char *reader, void *userdata) return 0; } -EUICC_SHARED_EXPORT int libapduinterface_init(struct euicc_apdu_interface *ifstruct) +static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) { memset(ifstruct, 0, sizeof(struct euicc_apdu_interface)); @@ -410,7 +408,7 @@ EUICC_SHARED_EXPORT int libapduinterface_init(struct euicc_apdu_interface *ifstr return 0; } -EUICC_SHARED_EXPORT int libapduinterface_main(int argc, char **argv) +static int libapduinterface_main(int argc, char **argv) { if (argc < 2) { @@ -454,3 +452,15 @@ EUICC_SHARED_EXPORT int libapduinterface_main(int argc, char **argv) return 0; } + +static void libapduinterface_fini(void) +{ +} + +const struct lpac_driver driver_apdu_pcsc = { + .type = DRIVER_APDU, + .name = "pcsc", + .init = (int (*)(void *))libapduinterface_init, + .main = libapduinterface_main, + .fini = libapduinterface_fini, +}; diff --git a/src/driver/apdu/pcsc.h b/src/driver/apdu/pcsc.h new file mode 100644 index 0000000..23b9b81 --- /dev/null +++ b/src/driver/apdu/pcsc.h @@ -0,0 +1,4 @@ +#pragma once +#include + +extern const struct lpac_driver driver_apdu_pcsc; diff --git a/interface/apdu/stdio.c b/src/driver/apdu/stdio.c similarity index 77% rename from interface/apdu/stdio.c rename to src/driver/apdu/stdio.c index fce8d68..d954b68 100644 --- a/interface/apdu/stdio.c +++ b/src/driver/apdu/stdio.c @@ -1,3 +1,5 @@ +#include "stdio.h" + #include #include #include @@ -5,93 +7,8 @@ #include #include - #include - -static int hexutil_bin2hex(char *output, uint32_t output_len, const uint8_t *bin, uint32_t bin_len) -{ - const char hexDigits[] = "0123456789abcdef"; - - if (!bin || !output) - { - return -1; - } - - if (output_len < (2 * bin_len + 1)) - { - return -1; - } - - for (uint32_t i = 0; i < bin_len; ++i) - { - char byte = bin[i]; - output[2 * i] = hexDigits[(byte >> 4) & 0x0F]; - output[2 * i + 1] = hexDigits[byte & 0x0F]; - } - output[2 * bin_len] = '\0'; - - return 0; -} - -static int hexutil_hex2bin(uint8_t *output, uint32_t output_len, const char *str, uint32_t str_len) -{ - uint32_t length; - - if (!str || !output || str_len % 2 != 0) - { - return -1; - } - - length = str_len / 2; - if (length > output_len) - { - return -1; - } - - for (uint32_t i = 0; i < length; ++i) - { - char high = str[2 * i]; - char low = str[2 * i + 1]; - - if (high >= '0' && high <= '9') - { - high -= '0'; - } - else if (high >= 'a' && high <= 'f') - { - high = high - 'a' + 10; - } - else if (high >= 'A' && high <= 'F') - { - high = high - 'A' + 10; - } - else - { - return -1; - } - - if (low >= '0' && low <= '9') - { - low -= '0'; - } - else if (low >= 'a' && low <= 'f') - { - low = low - 'a' + 10; - } - else if (low >= 'A' && low <= 'F') - { - low = low - 'A' + 10; - } - else - { - return -1; - } - - output[i] = (high << 4) + low; - } - - return length; -} +#include // getline is a GNU extension, Mingw32 macOS and FreeBSD don't have (a working) one static int afgets(char **obuf, FILE *fp) @@ -197,7 +114,7 @@ static int json_request(const char *func, const uint8_t *param, unsigned param_l { goto err; } - if (hexutil_bin2hex(param_hex, (2 * param_len) + 1, param, param_len) < 0) + if (euicc_hexutil_bin2hex(param_hex, (2 * param_len) + 1, param, param_len) < 0) { goto err; } @@ -306,7 +223,7 @@ static int json_response(int *ecode, uint8_t **data, uint32_t *data_len) { goto err; } - if (hexutil_hex2bin(*data, *data_len, jtmp->valuestring, strlen(jtmp->valuestring)) < 0) + if (euicc_hexutil_hex2bin_r(*data, *data_len, jtmp->valuestring, strlen(jtmp->valuestring)) < 0) { goto err; } @@ -407,7 +324,7 @@ static int apdu_interface_transmit(struct euicc_ctx *ctx, uint8_t **rx, uint32_t return ecode; } -EUICC_SHARED_EXPORT int libapduinterface_init(struct euicc_apdu_interface *ifstruct) +static int libapduinterface_init(struct euicc_apdu_interface *ifstruct) { ifstruct->connect = apdu_interface_connect; ifstruct->disconnect = apdu_interface_disconnect; @@ -418,7 +335,19 @@ EUICC_SHARED_EXPORT int libapduinterface_init(struct euicc_apdu_interface *ifstr return 0; } -EUICC_SHARED_EXPORT int libapduinterface_main(int argc, char **argv) +static int libapduinterface_main(int argc, char **argv) { return 0; } + +static void libapduinterface_fini(void) +{ +} + +const struct lpac_driver driver_apdu_stdio = { + .type = DRIVER_APDU, + .name = "stdio", + .init = (int (*)(void *))libapduinterface_init, + .main = libapduinterface_main, + .fini = libapduinterface_fini, +}; diff --git a/src/driver/apdu/stdio.h b/src/driver/apdu/stdio.h new file mode 100644 index 0000000..48c42fa --- /dev/null +++ b/src/driver/apdu/stdio.h @@ -0,0 +1,4 @@ +#pragma once +#include + +extern const struct lpac_driver driver_apdu_stdio; diff --git a/interface/http/CMakeLists.txt b/src/driver/http/CMakeLists.txt similarity index 100% rename from interface/http/CMakeLists.txt rename to src/driver/http/CMakeLists.txt diff --git a/src/driver/http/curl.c b/src/driver/http/curl.c new file mode 100644 index 0000000..78b9a8e --- /dev/null +++ b/src/driver/http/curl.c @@ -0,0 +1,205 @@ +#include "curl.h" +#include +#include +#include +#include + +#include + +#ifndef _WIN32 +#include +#else +#include +#define CURL_GLOBAL_DEFAULT ((1 << 0) | (1 << 1)) +#define CURLE_OK 0 +#define CURLOPT_URL 10002 +#define CURLOPT_WRITEFUNCTION 20011 +#define CURLOPT_WRITEDATA 10001 +#define CURLOPT_SSL_VERIFYPEER 64 +#define CURLOPT_SSL_VERIFYHOST 81 +#define CURLOPT_HTTPHEADER 10023 +#define CURLOPT_POSTFIELDS 10015 +#define CURLOPT_POSTFIELDSIZE 60 +#define CURLINFO_RESPONSE_CODE 2097154 + +typedef void CURL; +typedef int CURLcode; +typedef int CURLoption; +typedef int CURLINFO; + +static void *libcurl_interface_dlhandle = NULL; +#endif + +struct http_trans_response_data +{ + uint8_t *data; + size_t size; +}; + +static struct libcurl_interface +{ + CURLcode (*_curl_global_init)(long flags); + CURL *(*_curl_easy_init)(void); + CURLcode (*_curl_easy_setopt)(CURL *curl, CURLoption option, ...); + CURLcode (*_curl_easy_perform)(CURL *curl); + CURLcode (*_curl_easy_getinfo)(CURL *curl, CURLINFO info, ...); + const char *(*_curl_easy_strerror)(CURLcode); + void (*_curl_easy_cleanup)(CURL *curl); + + struct curl_slist *(*_curl_slist_append)(struct curl_slist *list, const char *data); + void (*_curl_slist_free_all)(struct curl_slist *list); +} libcurl; + +static size_t http_trans_write_callback(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + struct http_trans_response_data *mem = (struct http_trans_response_data *)userp; + + mem->data = realloc(mem->data, mem->size + realsize + 1); + if (mem->data == NULL) + { + /* out of memory! */ + printf("not enough memory (realloc returned NULL)\n"); + return 0; + } + + memcpy(&(mem->data[mem->size]), contents, realsize); + mem->size += realsize; + mem->data[mem->size] = 0; + + return realsize; +} + +static int http_interface_transmit(struct euicc_ctx *ctx, const char *url, uint32_t *rcode, uint8_t **rx, uint32_t *rx_len, const uint8_t *tx, uint32_t tx_len, const char **h) +{ + int fret = 0; + CURL *curl; + CURLcode res; + struct http_trans_response_data responseData = {0}; + struct curl_slist *headers = NULL, *nheaders = NULL; + long response_code; + + (*rx) = NULL; + (*rcode) = 0; + + curl = libcurl._curl_easy_init(); + if (!curl) + { + goto err; + } + + libcurl._curl_easy_setopt(curl, CURLOPT_URL, url); + libcurl._curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_trans_write_callback); + libcurl._curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&responseData); + libcurl._curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + libcurl._curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + for (int i = 0; h[i] != NULL; i++) + { + nheaders = libcurl._curl_slist_append(headers, h[i]); + if (nheaders == NULL) + { + goto err; + } + headers = nheaders; + } + libcurl._curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + if (tx != NULL) + { + libcurl._curl_easy_setopt(curl, CURLOPT_POSTFIELDS, tx); + libcurl._curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, tx_len); + } + + res = libcurl._curl_easy_perform(curl); + + if (res != CURLE_OK) + { + fprintf(stderr, "curl_easy_perform() failed: %s\n", libcurl._curl_easy_strerror(res)); + goto err; + } + + libcurl._curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + *rcode = response_code; + *rx = responseData.data; + *rx_len = responseData.size; + + fret = 0; + goto exit; + +err: + fret = -1; + free(responseData.data); +exit: + libcurl._curl_easy_cleanup(curl); + libcurl._curl_slist_free_all(headers); + return fret; +} + +static int _init_libcurl(void) +{ +#ifdef _WIN32 + if (!(libcurl_interface_dlhandle = dlopen("libcurl.dll", RTLD_LAZY))) + { + fprintf(stderr, "libcurl init err: %s\n", dlerror()); + return -1; + } + + libcurl._curl_global_init = dlsym(libcurl_interface_dlhandle, "curl_global_init"); + libcurl._curl_easy_init = dlsym(libcurl_interface_dlhandle, "curl_easy_init"); + libcurl._curl_easy_setopt = dlsym(libcurl_interface_dlhandle, "curl_easy_setopt"); + libcurl._curl_easy_perform = dlsym(libcurl_interface_dlhandle, "curl_easy_perform"); + libcurl._curl_easy_getinfo = dlsym(libcurl_interface_dlhandle, "curl_easy_getinfo"); + libcurl._curl_easy_strerror = dlsym(libcurl_interface_dlhandle, "curl_easy_strerror"); + libcurl._curl_easy_cleanup = dlsym(libcurl_interface_dlhandle, "curl_easy_cleanup"); + libcurl._curl_slist_append = dlsym(libcurl_interface_dlhandle, "curl_slist_append"); + libcurl._curl_slist_free_all = dlsym(libcurl_interface_dlhandle, "curl_slist_free_all"); +#else + libcurl._curl_global_init = curl_global_init; + libcurl._curl_easy_init = curl_easy_init; + libcurl._curl_easy_setopt = curl_easy_setopt; + libcurl._curl_easy_perform = curl_easy_perform; + libcurl._curl_easy_getinfo = curl_easy_getinfo; + libcurl._curl_easy_strerror = curl_easy_strerror; + libcurl._curl_easy_cleanup = curl_easy_cleanup; + libcurl._curl_slist_append = curl_slist_append; + libcurl._curl_slist_free_all = curl_slist_free_all; +#endif + + return 0; +} + +static int libhttpinterface_init(struct euicc_http_interface *ifstruct) +{ + memset(ifstruct, 0, sizeof(struct euicc_http_interface)); + + if (_init_libcurl() != 0) + { + return -1; + } + + if (libcurl._curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) + { + return -1; + } + + ifstruct->transmit = http_interface_transmit; + + return 0; +} + +static int libhttpinterface_main(int argc, char **argv) +{ + return 0; +} + +static void libhttpinterface_fini(void) +{ +} + +const struct lpac_driver driver_http_curl = { + .type = DRIVER_HTTP, + .name = "curl", + .init = (int (*)(void *))libhttpinterface_init, + .main = libhttpinterface_main, + .fini = libhttpinterface_fini, +}; diff --git a/src/driver/http/curl.h b/src/driver/http/curl.h new file mode 100644 index 0000000..83515fa --- /dev/null +++ b/src/driver/http/curl.h @@ -0,0 +1,4 @@ +#pragma once +#include + +extern const struct lpac_driver driver_http_curl; diff --git a/interface/http/stdio.c b/src/driver/http/stdio.c similarity index 70% rename from interface/http/stdio.c rename to src/driver/http/stdio.c index 20e8316..1428f0c 100644 --- a/interface/http/stdio.c +++ b/src/driver/http/stdio.c @@ -1,3 +1,5 @@ +#include "stdio.h" + #include #include #include @@ -5,93 +7,8 @@ #include #include - #include - -static int hexutil_bin2hex(char *output, uint32_t output_len, const uint8_t *bin, uint32_t bin_len) -{ - const char hexDigits[] = "0123456789abcdef"; - - if (!bin || !output) - { - return -1; - } - - if (output_len < (2 * bin_len + 1)) - { - return -1; - } - - for (uint32_t i = 0; i < bin_len; ++i) - { - char byte = bin[i]; - output[2 * i] = hexDigits[(byte >> 4) & 0x0F]; - output[2 * i + 1] = hexDigits[byte & 0x0F]; - } - output[2 * bin_len] = '\0'; - - return 0; -} - -static int hexutil_hex2bin(uint8_t *output, uint32_t output_len, const char *str, uint32_t str_len) -{ - uint32_t length; - - if (!str || !output || str_len % 2 != 0) - { - return -1; - } - - length = str_len / 2; - if (length > output_len) - { - return -1; - } - - for (uint32_t i = 0; i < length; ++i) - { - char high = str[2 * i]; - char low = str[2 * i + 1]; - - if (high >= '0' && high <= '9') - { - high -= '0'; - } - else if (high >= 'a' && high <= 'f') - { - high = high - 'a' + 10; - } - else if (high >= 'A' && high <= 'F') - { - high = high - 'A' + 10; - } - else - { - return -1; - } - - if (low >= '0' && low <= '9') - { - low -= '0'; - } - else if (low >= 'a' && low <= 'f') - { - low = low - 'a' + 10; - } - else if (low >= 'A' && low <= 'F') - { - low = low - 'A' + 10; - } - else - { - return -1; - } - - output[i] = (high << 4) + low; - } - - return length; -} +#include // getline is a GNU extension, Mingw32 macOS and FreeBSD don't have (a working) one static int afgets(char **obuf, FILE *fp) @@ -196,7 +113,7 @@ static int json_request(const char *url, const uint8_t *tx, uint32_t tx_len, con { goto err; } - if (hexutil_bin2hex(tx_hex, (2 * tx_len) + 1, tx, tx_len) < 0) + if (euicc_hexutil_bin2hex(tx_hex, (2 * tx_len) + 1, tx, tx_len) < 0) { goto err; } @@ -321,7 +238,7 @@ static int http_interface_transmit(struct euicc_ctx *ctx, const char *url, uint3 { goto err; } - if (hexutil_hex2bin(*rx, *rx_len, jtmp->valuestring, strlen(jtmp->valuestring)) < 0) + if (euicc_hexutil_hex2bin_r(*rx, *rx_len, jtmp->valuestring, strlen(jtmp->valuestring)) < 0) { goto err; } @@ -341,7 +258,7 @@ exit: return fret; } -EUICC_SHARED_EXPORT int libhttpinterface_init(struct euicc_http_interface *ifstruct) +static int libhttpinterface_init(struct euicc_http_interface *ifstruct) { memset(ifstruct, 0, sizeof(struct euicc_http_interface)); @@ -350,7 +267,19 @@ EUICC_SHARED_EXPORT int libhttpinterface_init(struct euicc_http_interface *ifstr return 0; } -EUICC_SHARED_EXPORT int libhttpinterface_main(int argc, char **argv) +static int libhttpinterface_main(int argc, char **argv) { return 0; } + +static void libhttpinterface_fini(void) +{ +} + +const struct lpac_driver driver_http_stdio = { + .type = DRIVER_HTTP, + .name = "stdio", + .init = (int (*)(void *))libhttpinterface_init, + .main = libhttpinterface_main, + .fini = libhttpinterface_fini, +}; diff --git a/src/driver/http/stdio.h b/src/driver/http/stdio.h new file mode 100644 index 0000000..83f530d --- /dev/null +++ b/src/driver/http/stdio.h @@ -0,0 +1,4 @@ +#pragma once +#include + +extern const struct lpac_driver driver_http_stdio; diff --git a/src/main.c b/src/main.c index 19d1818..6f554c1 100644 --- a/src/main.c +++ b/src/main.c @@ -8,8 +8,7 @@ #include #include -#include "dlsym_interface.h" - +#include "driver.h" #include "applet.h" #include "applet/chip.h" #include "applet/profile.h" @@ -17,7 +16,7 @@ #include "applet/version.h" static const struct applet_entry *applets[] = { - &applet_dlsym_interface, + &driver_applet, &applet_chip, &applet_profile, &applet_notification, @@ -54,17 +53,19 @@ int main(int argc, char **argv) memset(&euicc_ctx, 0, sizeof(euicc_ctx)); - if (dlsym_interface_init()) + if (driver_init()) { return -1; } - euicc_ctx.apdu.interface = &dlsym_apdu_interface; - euicc_ctx.http.interface = &dlsym_http_interface; + euicc_ctx.apdu.interface = &driver_interface_apdu; + euicc_ctx.http.interface = &driver_interface_http; ret = applet_entry(argc, argv, applets); main_fini_euicc(); + driver_fini(); + return ret; }