From: Manasij Sur Roy Date: Mon, 28 Dec 2015 12:14:57 +0000 (+0530) Subject: Initial 3.0 public version X-Git-Tag: submit/tizen_mobile/20160115.025345~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F71%2F55671%2F1;p=platform%2Fcore%2Faccount%2Ffido-client.git Initial 3.0 public version Change-Id: I59f9eb2fc7e42440550b14b731fc4665db1aa397 Signed-off-by: Manasij Sur Roy --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..080e5b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.config +*.creator +*.user +*.files +*.includes diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9ace45f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(fido-client C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include ") +SET(VERSION_MAJOR 0) +SET(VERSION "${VERSION_MAJOR}.0.1") + +ADD_SUBDIRECTORY(client) +ADD_SUBDIRECTORY(fido_svc_ui) +ADD_SUBDIRECTORY(server) +ADD_DEPENDENCIES(fido-service fido-ui-service) +#INSTALL(DIRECTORY lib/fido/asm/ DESTINATION lib/fido/asm/) +ADD_SUBDIRECTORY(test/Dummy_ASM_DBUS) +ADD_SUBDIRECTORY(test/Fido_Sample_RPM) +ADD_SUBDIRECTORY(test/shell_tc) diff --git a/LICENSE.Apache-2.0 b/LICENSE.Apache-2.0 new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE.Apache-2.0 @@ -0,0 +1,202 @@ + + 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. diff --git a/NOTICE b/NOTICE new file mode 100755 index 0000000..0e0f016 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License terms and conditions. diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100644 index 0000000..b8e4f66 --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,61 @@ + +SET(CLIENT_SRCS + fido_uaf_client.c + fido_uaf_authenticator.c + ../common/fido_json_handler.c + ../common/fido_b64_util.c + ../common/fido_tlv_util.c + ../common/fido_uaf_utils.c +) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) + +INCLUDE(FindPkgConfig) +pkg_check_modules(CLIENT_PKGS REQUIRED + dlog + glib-2.0 + gio-unix-2.0 + capi-base-common + json-glib-1.0 + openssl +) + +FOREACH(flag ${CLIENT_PKGS_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror") +SET(CMAKE_LDFLAGS "-Wl,-zdefs") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"") +ADD_DEFINITIONS("-DSLP_DEBUG") + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_SOURCE_DIR}/common/fido-stub.c ${CMAKE_SOURCE_DIR}/common/fido-stub.h +WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/common/ +COMMAND gdbus-codegen --interface-prefix org.tizen. --generate-c-code fido-stub ${CMAKE_SOURCE_DIR}/common/dbus_interfaces/fido.xml +COMMENT "Generating FIDO GDBus stubs........................") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${CLIENT_SRCS} ${CMAKE_SOURCE_DIR}/common/fido-stub.c) +ADD_DEPENDENCIES(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/common/fido-stub.h) +ADD_DEPENDENCIES(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/common/fido-stub.c) + +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${CLIENT_PKGS_LDFLAGS}) + +#CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) + +##INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib/fido) +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) +#INSTALL(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig) + +INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/fido.h DESTINATION include) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/fido_uaf_authenticator.h DESTINATION include) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/fido_uaf_client.h DESTINATION include) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/common/fido_uaf_types.h DESTINATION include) + +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/client/${PROJECT_NAME}.pc.in ${CMAKE_SOURCE_DIR}/client/${PROJECT_NAME}.pc @ONLY) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/client/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig) diff --git a/client/fido-client.pc.in b/client/fido-client.pc.in new file mode 100644 index 0000000..92ba8eb --- /dev/null +++ b/client/fido-client.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: fido-client +Description: Tizen FIDO Client +Version: @VERSION@ +#Requires: capi-base-common +Libs: -L${libdir} -lfido-client +Cflags: -I${includedir} diff --git a/client/fido_uaf_authenticator.c b/client/fido_uaf_authenticator.c new file mode 100755 index 0000000..9d48020 --- /dev/null +++ b/client/fido_uaf_authenticator.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "fido_internal_types.h" +#include "fido_uaf_authenticator.h" +#include "fido_logs.h" + +EXPORT_API int +fido_authenticator_get_title(const fido_authenticator_h auth, char **title) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + RET_IF_FAIL(title != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + RET_IF_FAIL(priv->title != NULL, FIDO_ERROR_INVALID_PARAMETER); + + *title = strdup(priv->title); + + RET_IF_FAIL(title == NULL, FIDO_ERROR_OUT_OF_MEMORY); + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_aaid(const fido_authenticator_h auth, char **aaid) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + RET_IF_FAIL(aaid != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + RET_IF_FAIL(priv->aaid != NULL, FIDO_ERROR_INVALID_PARAMETER); + + *aaid = strdup(priv->aaid); + + RET_IF_FAIL(aaid == NULL, FIDO_ERROR_OUT_OF_MEMORY); + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_description(const fido_authenticator_h auth, char **desc) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + RET_IF_FAIL(desc != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + RET_IF_FAIL(priv->description != NULL, FIDO_ERROR_INVALID_PARAMETER); + + *desc = strdup(priv->description); + + RET_IF_FAIL(desc == NULL, FIDO_ERROR_OUT_OF_MEMORY); + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_assertion_scheme(const fido_authenticator_h auth, char **scheme) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + RET_IF_FAIL(scheme != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + RET_IF_FAIL(priv->assertion_scheme != NULL, FIDO_ERROR_INVALID_PARAMETER); + + *scheme = strdup(priv->assertion_scheme); + + RET_IF_FAIL(scheme == NULL, FIDO_ERROR_OUT_OF_MEMORY); + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_algorithm(const fido_authenticator_h auth, fido_auth_algo_e *algo) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + *algo = priv->authentication_algorithm; + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_foreach_attestation_type(const fido_authenticator_h auth, fido_attestation_type_cb cb, +void *user_data) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + if (priv->attestation_types == NULL + || g_list_length(priv->attestation_types) <= 0) + return FIDO_ERROR_NO_DATA; + + GList *list_iter = g_list_first(priv->attestation_types); + while (list_iter != NULL) { + int att_type = GPOINTER_TO_INT(list_iter->data); + + (cb)(att_type, user_data); + + list_iter = list_iter->next; + } + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_verification_method(const fido_authenticator_h auth, fido_auth_user_verify_type_e *user_verification) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + *user_verification = priv->user_verification; + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_key_protection_method(const fido_authenticator_h auth, fido_auth_key_protection_type_e *key_protection) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + *key_protection = priv->key_protection; + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_matcher_protection_method(const fido_authenticator_h auth, fido_auth_matcher_protection_type_e *matcher_protection) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + *matcher_protection = priv->matcher_protection; + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_attachment_hint(const fido_authenticator_h auth, fido_auth_attachment_hint_e *attachment_hint) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + *attachment_hint = priv->attachment_hint; + + return FIDO_ERROR_NONE; +} + +EXPORT_API bool +fido_authenticator_get_is_second_factor_only(const fido_authenticator_h auth) +{ + RET_IF_FAIL(auth != NULL, false); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + return priv->is_second_factor_only; +} + +EXPORT_API int +fido_authenticator_get_tc_discplay(const fido_authenticator_h auth, fido_auth_tc_display_type_e *tc_display) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + *tc_display = priv->tc_display; + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_tc_display_type(const fido_authenticator_h auth, char **tc_display_content_type) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + RET_IF_FAIL(tc_display_content_type != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + RET_IF_FAIL(priv->tc_display_content_type != NULL, FIDO_ERROR_INVALID_PARAMETER); + + *tc_display_content_type = strdup(priv->tc_display_content_type); + + RET_IF_FAIL(tc_display_content_type == NULL, FIDO_ERROR_OUT_OF_MEMORY); + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_authenticator_get_icon(const fido_authenticator_h auth, char **icon) +{ + RET_IF_FAIL(auth != NULL, FIDO_ERROR_INVALID_PARAMETER); + + RET_IF_FAIL(icon != NULL, FIDO_ERROR_INVALID_PARAMETER); + + fido_authenticator_s *priv = (fido_authenticator_s*)auth; + + RET_IF_FAIL(priv->icon != NULL, FIDO_ERROR_INVALID_PARAMETER); + + *icon = strdup(priv->icon); + + RET_IF_FAIL(icon == NULL, FIDO_ERROR_OUT_OF_MEMORY); + + return FIDO_ERROR_NONE; +} + diff --git a/client/fido_uaf_client.c b/client/fido_uaf_client.c new file mode 100755 index 0000000..8500b60 --- /dev/null +++ b/client/fido_uaf_client.c @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include "fido_uaf_client.h" +#include "fido_logs.h" +#include "fido_internal_types.h" +#include "fido_json_handler.h" +#include "fido-stub.h" +#include "fido_keys.h" +#include "fido_uaf_authenticator.h" + +static Fido *_fido_dbus_obj = NULL; + +typedef struct _fido_process_cb_data { + fido_uaf_response_message_cb cb; + void *user_data; +} _fido_process_cb_data_s; + + +static void +init_dbus(void) +{ + _INFO("init_dbus"); +#if !GLIB_CHECK_VERSION(2,35,0) + g_type_init(); +#endif + + GDBusConnection *connection = NULL; + GError *error = NULL; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + + _INFO("after g_bus_get_sync"); + + + /* Create the object */ + _fido_dbus_obj = fido_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, + _FIDO_DBUS_NAME, + _FIDO_DBUS_PATH, + NULL, + &error); +} + +Fido * +_dbus_proxy_get_instance(int time_out) +{ + _INFO("_dbus_proxy_get_instance singleton"); + + static pthread_once_t onceBlock = PTHREAD_ONCE_INIT; + if (_fido_dbus_obj == NULL) { + pthread_once(&onceBlock, init_dbus); + if (_fido_dbus_obj == NULL) { + _ERR("init_dbus failed"); + onceBlock = PTHREAD_ONCE_INIT; + } + } + _INFO("_dbus_proxy_get_instance end"); + + g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(_fido_dbus_obj), time_out); + + return _fido_dbus_obj; +} + +static void +_fido_uaf_process_operation_reply(GObject *object, GAsyncResult *res, gpointer user_data) +{ + _INFO("_fido_uaf_process_operation_reply"); + + GError *dbus_err = NULL; + + if (user_data == NULL) { + _ERR("Can not proceed since callback data is NULL"); + return; + } + + _fido_process_cb_data_s *cb_data = (_fido_process_cb_data_s *)user_data; + if (cb_data == NULL) { + _ERR("Can not proceed since callback data is NULL"); + return; + } + + if (cb_data->cb == NULL) { + _ERR("Can not proceed since callback data's cb part is NULL"); + SAFE_DELETE(cb_data); + return; + } + + int tizen_err = FIDO_ERROR_NONE; + + char *uaf_response_json = NULL; + + fido_call_fido_uaf_process_operation_finish(_fido_dbus_obj, &tizen_err, &uaf_response_json, + res, &dbus_err); + + if (dbus_err) { + _ERR("fido_foreach_authenticator failed [%s]", dbus_err->message); + if (tizen_err == FIDO_ERROR_NONE) + tizen_err = FIDO_ERROR_PERMISSION_DENIED; + /* Error is notified via tizen_err and/or fido_err, so no need to get dbus error*/ + } + + g_clear_error(&dbus_err); + + if (strcmp(uaf_response_json, _EMPTY_JSON_STRING) == 0) + (cb_data->cb)(tizen_err, NULL, cb_data->user_data); + else + (cb_data->cb)(tizen_err, uaf_response_json, cb_data->user_data); + + _INFO("After calling fido_uaf_response_message_cb"); + + SAFE_DELETE(cb_data); + SAFE_DELETE(uaf_response_json); +} + +EXPORT_API int +fido_foreach_authenticator(fido_authenticator_cb callback, void *user_data) +{ + if (callback == NULL) { + _ERR("callback can not be NULL [FIDO_ERROR_INVALID_PARAMETER]"); + return FIDO_ERROR_INVALID_PARAMETER; + } + + Fido *dbus_proxy = _dbus_proxy_get_instance(_DBUS_TIMEOUT_USE_DEFAULT); + if (dbus_proxy == NULL) { + _ERR("DBus proxy failed"); + return FIDO_ERROR_NOT_SUPPORTED; + } + + gchar **discovery_data_json = NULL; + int discovery_data_json_list_len = 0; + int tz_err = 0; + GError *dbus_err = NULL; + fido_call_fido_uaf_discover_sync(dbus_proxy, &tz_err, &discovery_data_json, &discovery_data_json_list_len, + NULL, &dbus_err); + + + if (dbus_err != NULL) { + _ERR("fido_call_fido_uaf_discover_sync failed [%s]", dbus_err->message); + g_clear_error(&dbus_err); + + return FIDO_ERROR_PERMISSION_DENIED; + } + + if (discovery_data_json == NULL || discovery_data_json_list_len <= 0) { + _ERR("No Authenticators found"); + return FIDO_ERROR_NOT_SUPPORTED; + } + + _INFO("ASM response len =[%d]", discovery_data_json_list_len); + + tz_err = FIDO_ERROR_NONE; + + int parser_err = 0; + GList *auth_list = _uaf_parser_parse_asm_response_discover_client(discovery_data_json, + discovery_data_json_list_len, &parser_err); + if (parser_err != FIDO_ERROR_NONE) { + tz_err = _convert_asm_status_code_to_uaf_error(parser_err); + } + else { + + if (g_list_length(auth_list) <= 0) { + tz_err = FIDO_ERROR_NOT_SUPPORTED; + } + else { + + GList *auth_list_iter = g_list_first(auth_list); + while (auth_list_iter != NULL) { + + fido_authenticator_s *auth_priv = (fido_authenticator_s *)(auth_list_iter->data); + (callback)((fido_authenticator_h)auth_priv, user_data); + auth_list_iter = auth_list_iter->next; + } + } + } + + int i = 0; + for (; i < discovery_data_json_list_len; i++) + SAFE_DELETE(discovery_data_json[i]); + + SAFE_DELETE(discovery_data_json); + + /*Items are deleted after callback is done for elements, so apps must make a local copy of elements if they + want to use them later*/ + g_list_free_full(auth_list, _free_asm_auth_list); + + return tz_err; +} + +EXPORT_API int +fido_get_client_vendor(char **vendor_name) +{ + if (vendor_name == NULL) + return FIDO_ERROR_INVALID_PARAMETER; + + char *vn_temp = (char*)calloc(1, _CLIENT_VENDOR_NAME_MAX_SIZE + 1); + strncpy(vn_temp, _CLIENT_VENDOR_NAME, _CLIENT_VENDOR_NAME_MAX_SIZE); + + *vendor_name = vn_temp; + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_get_client_version(int *client_major_version, int *client_minor_version) +{ + if ((client_major_version == NULL) || (client_minor_version == NULL)) + return FIDO_ERROR_INVALID_PARAMETER; + + *client_major_version = _CLIENT_VERSION_MAJOR; + *client_minor_version = _CLIENT_VERSION_MINOR; + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_uaf_is_supported(const char *uaf_message_json, bool *is_supported) +{ + if (uaf_message_json == NULL) { + _ERR("uaf_message_json can not be NULL [FIDO_ERROR_INVALID_PARAMETER]"); + return FIDO_ERROR_INVALID_PARAMETER; + } + + Fido *dbus_proxy = _dbus_proxy_get_instance(_DBUS_TIMEOUT_USE_DEFAULT); + if (dbus_proxy == NULL) { + _ERR("DBus proxy failed"); + return FIDO_ERROR_NOT_SUPPORTED; + } + + int tz_err = FIDO_ERROR_NONE; + GError *dbus_err = NULL; + fido_call_fido_uaf_check_policy_sync(dbus_proxy, uaf_message_json, &tz_err, + NULL, &dbus_err); + + if (dbus_err != NULL) { + _ERR("fido_call_fido_uaf_check_policy_sync failed [%s]", dbus_err->message); + g_clear_error(&dbus_err); + return FIDO_ERROR_PERMISSION_DENIED; + } + + if (tz_err == FIDO_ERROR_NONE) + *is_supported = true; + else + *is_supported = false; + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_uaf_get_response_message(const char *uaf_request_json, const char *channel_binding_json, + fido_uaf_response_message_cb callback, void *user_data) +{ + if (callback == NULL) { + _ERR("callback can not be NULL [FIDO_ERROR_INVALID_PARAMETER]"); + return FIDO_ERROR_INVALID_PARAMETER; + } + if (uaf_request_json == NULL) { + _ERR("uaf_request_json can not be NULL [FIDO_ERROR_INVALID_PARAMETER]"); + return FIDO_ERROR_INVALID_PARAMETER; + } + + Fido *dbus_proxy = _dbus_proxy_get_instance(_DBUS_TIMEOUT_INFINITE); + if (dbus_proxy == NULL) { + _ERR("DBus proxy failed"); + return FIDO_ERROR_NOT_SUPPORTED; + } + + _fido_process_cb_data_s *cb_data = (_fido_process_cb_data_s *) calloc(1, sizeof(_fido_process_cb_data_s)); + cb_data->cb = callback; + cb_data->user_data = user_data; + + if (channel_binding_json != NULL) { + fido_call_fido_uaf_process_operation(dbus_proxy, uaf_request_json, channel_binding_json, + NULL, _fido_uaf_process_operation_reply, cb_data); + } + else { + fido_call_fido_uaf_process_operation(dbus_proxy, uaf_request_json, + _FIDO_NO_CHANNEL_BINDING_DBUS_STRING, + NULL, _fido_uaf_process_operation_reply, cb_data); + } + + return FIDO_ERROR_NONE; +} + +EXPORT_API int +fido_uaf_set_server_result(int response_code, const char *uaf_response_json) +{ + if (uaf_response_json == NULL) { + _ERR("uaf_response_json can not be NULL [FIDO_ERROR_INVALID_PARAMETER]"); + return FIDO_ERROR_INVALID_PARAMETER; + } + + Fido *dbus_proxy = _dbus_proxy_get_instance(_DBUS_TIMEOUT_USE_DEFAULT); + if (dbus_proxy == NULL) { + _ERR("DBus proxy failed"); + return FIDO_ERROR_NOT_SUPPORTED; + } + + GError *dbus_err = NULL; + + int tizen_error_code = FIDO_ERROR_NONE; + + _response_t *uaf_res_data = _uaf_parser_parse_uaf_response(uaf_response_json); + if (uaf_res_data == NULL) + return FIDO_ERROR_PROTOCOL_ERROR; + + if (response_code == FIDO_SERVER_STATUS_CODE_OK) { + _free_response(uaf_res_data); + return FIDO_ERROR_NONE; + } + + + _INFO("before checking operation name"); + if (strcmp(uaf_res_data->header->operation, _UAF_OPERATION_NAME_KEY_REG) != 0) { + _free_response(uaf_res_data); + return FIDO_ERROR_NONE; + } + + /*Only for reg response, if not success code, then delete the reg*/ + + _INFO("before calling _uaf_composer_compose_dereg_request"); + char *uaf_dereg_json = _uaf_composer_compose_dereg_request(uaf_res_data); + + _free_response(uaf_res_data); + + if (uaf_dereg_json == NULL) + return FIDO_ERROR_PROTOCOL_ERROR; + + int tz_err = FIDO_ERROR_NONE; + char *resp = 0; + + GError *err = NULL; + gboolean is_success = fido_call_fido_uaf_process_operation_sync(dbus_proxy, + uaf_dereg_json, + _FIDO_NO_CHANNEL_BINDING_DBUS_STRING, &tz_err, + &resp, NULL, &err); + + if (is_success == FALSE) { + _ERR("fido_call_fido_uaf_notify_result_sync failed [%d]", tizen_error_code); + if (dbus_err) { + _ERR("GError = [%s]", dbus_err->message); + } + return FIDO_ERROR_PROTOCOL_ERROR; + } + + return tz_err; +} diff --git a/common/dbus_interfaces/dummyasm.xml b/common/dbus_interfaces/dummyasm.xml new file mode 100644 index 0000000..a54a108 --- /dev/null +++ b/common/dbus_interfaces/dummyasm.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/common/dbus_interfaces/fido.xml b/common/dbus_interfaces/fido.xml new file mode 100644 index 0000000..912ad15 --- /dev/null +++ b/common/dbus_interfaces/fido.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/fido_b64_util.c b/common/fido_b64_util.c new file mode 100644 index 0000000..914e66e --- /dev/null +++ b/common/fido_b64_util.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + #include + +#include "fido_logs.h" +#include "fido_internal_types.h" +#include "fido_b64_util.h" + +int +_fido_b64url_encode(const unsigned char *input, int inlen, unsigned char *output, int *outlen) +{ + _INFO("_fido_b64url_encode start"); + + BIO * bmem = NULL; + BIO * b64 = NULL; + BUF_MEM * bptr = NULL; + b64 = BIO_new(BIO_f_base64()); + if(b64 == NULL) { + _ERR("BIO_new with BIO_f_base64 failed "); + return -1; + } + + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + + bmem = BIO_new(BIO_s_mem()); + b64 = BIO_push(b64, bmem); + BIO_write(b64, input, inlen); + BIO_flush(b64); + BIO_get_mem_ptr(b64, &bptr); + + memcpy(output, bptr->data, bptr->length); + output[bptr->length] = 0; + *outlen = bptr->length; + + int i; + for(i =0; i < *outlen ; i++) { + if(output[i] == '+') + output[i] = '-'; + + else if(output[i] == '/') + output[i] = '_'; + + else if(output[i] == '=') { + *outlen = i ; + output[i] = '\0'; + break; + } + } + + BIO_free_all(b64); + + _INFO("%s", output); + _INFO("_fido_b64url_encode end"); + + return 0; +} + +int +_fido_b64url_decode(const unsigned char *in, int inlen, + unsigned char *out, int *outlen) +{ + _INFO("_fido_b64url_decode start"); + + int npadChars = (inlen %4) == 0 ? 0 : (4 - (inlen%4)); + unsigned char *base64 = (unsigned char *) malloc(inlen + npadChars); + if(base64 == NULL) { + _ERR("malloc failed"); + return -1; + } + + memcpy(base64, in, inlen); + + int i; + for(i =0; i < inlen ; i++) { + if(base64[i] == '-') + base64[i] = '+'; + + else if(base64[i] == '_') + base64[i] = '/'; + + } + + if(npadChars != 0) + memset(base64 + inlen, '=', npadChars); + + BIO * b64 = NULL; + BIO * bmem = NULL; + b64 = BIO_new(BIO_f_base64()); + if(b64 == NULL) { + _ERR("BIO_new with BIO_f_base64 failed"); + + SAFE_DELETE(base64); + return -1; + } + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + bmem = BIO_new_mem_buf(base64, inlen); + if(bmem == NULL) { + _ERR("BIO_new_mem_buf failed"); + + SAFE_DELETE(base64); + return -1; + } + + bmem = BIO_push(b64, bmem); + *outlen = BIO_read(bmem, out, inlen); + if(*outlen <= 0) { + _ERR("BIO_read failed"); + + SAFE_DELETE(base64); + return -1; + } + + if(bmem) + BIO_free_all(bmem); + + _INFO("_fido_b64url_decode end"); + + return 0; +} diff --git a/common/fido_b64_util.h b/common/fido_b64_util.h new file mode 100644 index 0000000..c5ffbc4 --- /dev/null +++ b/common/fido_b64_util.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _FIDO_B64_UTIL_H +#define _FIDO_B64_UTIL_H + +#include +#include + +int _fido_b64url_encode(const unsigned char *input, int inlen, unsigned char *output, int *outlen); + +int _fido_b64url_decode(const unsigned char *in, int inlen, unsigned char *out, int *outlen); + +#endif diff --git a/common/fido_internal_types.h b/common/fido_internal_types.h new file mode 100644 index 0000000..90dac32 --- /dev/null +++ b/common/fido_internal_types.h @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef FIDO_INTERNAL_TYPES_H +#define FIDO_INTERNAL_TYPES_H + +#include +#include +#include +#include +#include +#include "fido_uaf_types.h" + +#define RET_IF_FAIL_VOID(cond) do {\ + if (!(cond)){\ + return;\ + }\ +} while(0) + +#define RET_IF_FAIL(cond, err) do {\ + if (!(cond)){\ + return err;\ + }\ +} while(0) + +#define CATCH_IF_FAIL(cond) do {\ + if (!(cond)){\ + goto CATCH;\ + }\ +} while(0) + +#define CATCH_IF_FAIL_X(cond, expr) do {\ + if (!(cond)){\ + expr;\ + goto CATCH;\ + }\ +} while(0) + +#define GOTO_IF_FAIL(cond, catch_block) do {\ + if (!(cond)){\ + goto catch_block;\ + }\ +} while(0) + +#define SAFE_DELETE(x) do {\ + if (x != NULL) {\ + free(x); \ + x = NULL;\ + }\ +} while(0) + +#define _SAFE_DUP(x) ((x) ? strdup(x) : NULL) + +/* UAF API structures start */ +/** + * @brief UAF version structure. + * @since_tizen 3.0 + */ +typedef struct _fido_version_s { + int major;/** Major version **/ + int minor;/** Minor version **/ +} fido_version_s; + +typedef struct _fido_rgb_pallette_entry_s { + unsigned short r;/** Red component**/ + unsigned short g;/** Green component**/ + unsigned short b;/** Blue component**/ +} fido_rgb_pallette_entry_s; + +typedef struct _fido_display_png_characteristics_descriptor_s { + unsigned long width;/** Width**/ + unsigned long height;/** Height**/ + uint8_t bit_depth;/** Bit depth**/ + uint8_t color_type;/** Color type**/ + uint8_t compression;/** Compression**/ + uint8_t filter;/** Filter**/ + uint8_t interlace;/** Interlace**/ + GList *plte;/** Pallete entry list of type @c List of @c fido_rgb_pallette_entry_t elements **/ +} fido_display_png_characteristics_descriptor_s; + +void _free_display_png_characteristics_descriptor(fido_display_png_characteristics_descriptor_s *data); + + +/* UAF API structures end */ + + +typedef struct _version { + int major; + int minor; +} _version_t; + +typedef struct _extension { + char *id; + char *data; + bool fail_if_unknown; +} _extension_t; + +void _free_extension(_extension_t *data); + +typedef struct _match_criteria { + GList *aaid_list; + GList *vendor_list; + GList *key_id_list; + long long int user_verification; + int key_protection; + int matcher_protection; + long long int attachement_hint; + int tc_display; + GList *auth_algo_list; + GList *assertion_scheme_list; + GList *attestation_type_list; + int auth_version; + GList *extension_list; + +} _match_criteria_t; + +void _free_match_criteria(_match_criteria_t *data); + +typedef struct _policy { + GList *accepted_list;//2d array + GList *disallowed_list; + bool is_keyid_present; /*Only call GetRegistrations ASM call if atleast one match criteria contains keyIDs*/ +} _policy_t; + +void _free_policy(_policy_t *data); + +typedef struct _op_header { + _version_t *version; + char *operation; + char *app_id; + char *server_data; + GList *ext_list; +}_op_header_t; + +void _free_op_header(_op_header_t *data); + +typedef enum { + _MESSAGE_TYPE_MIN = -1, + _MESSAGE_TYPE_REG, + _MESSAGE_TYPE_AUTH, + _MESSAGE_TYPE_DEREG, + _MESSAGE_TYPE_MAX +}_message_type_e; + +typedef struct _message { + char *facet_id; + _op_header_t *header; + char *channel_binding; + _message_type_e type; + void *data;/* type can be _reg_request_t / _auth_request_t / _dereg_request_t depending on header->operation */ +} _message_t; + +void _free_message(_message_t *data); + +typedef struct _reg_request { + char *challenge; + char *user_name; + _policy_t *policy; +} _reg_request_t; + +void _free_reg_request(_reg_request_t *data); + +typedef struct _auth_transaction { + char *content_type; + char *content; + fido_display_png_characteristics_descriptor_s *display_charac; +}_auth_transaction_t; + +void _free_auth_transaction(_auth_transaction_t *data); + +typedef struct _auth_request { + char *challenge; + GList *transaction_list; + _policy_t *policy; +} _auth_request_t; + +void _free_auth_request(_auth_request_t *data); + +typedef struct _dereg_auth_info { + char *aaid; + char *key_id; +} _dereg_auth_info_t; + +void _free_dereg_auth_info(_dereg_auth_info_t *data); + +typedef struct _dereg_request { + GList *auth_info_list; +} _dereg_request_t; + +void _free_dereg_request(_dereg_request_t *data); + +typedef struct _fido_asm_version { + int major; + int minor; +} _fido_asm_version_t; + + +typedef struct _fido_asm_rgb_pallette_entry { + unsigned short r; + unsigned short g; + unsigned short b; +} _fido_asm_rgb_pallette_entry_t; + + +typedef struct _fido_asm_display_png_characteristics_descriptor { + unsigned long width; + unsigned long height; + int bit_depth; + int color_type; + int compression; + int filter; + int interlace; + GList *plte; +} _fido_asm_display_png_characteristics_descriptor_t; + +void _free_asm_display_png_characteristics_descriptor_t(_fido_asm_display_png_characteristics_descriptor_t *data); + +typedef struct _fido_asm_proxy { + char *asm_id; + char *vendor; + char *bin_path; + char *dbus_info; + char *dbus_obj_path; + char *dbus_interface_name; + char *dbus_method_name; + GDBusProxy *dbus_proxy; +} _fido_asm_proxy_t; + +void _free_fido_asm_proxy(void *data); + +typedef struct _asm_discover_response { + int error_code; + char *asm_id; + char *asm_response_json; +} _asm_discover_response_t; + +void _free_asm_discover_response(_asm_discover_response_t *data); + +typedef struct _fido_asm_authenticator { + GList *supported_versions; + char *asm_id; + char *auth_index; + GList *key_ids;//filled up from GetRegistrations request to ASM + GList *asm_versions; + bool is_user_enrolled; + bool has_settings; + char *aaid; + char *assertion_scheme; + int authentication_algorithm; + GList *attestation_types; + unsigned long user_verification; + int key_protection; + int matcher_protection; + unsigned long attachment_hint; + bool is_second_factor_only; + bool is_roaming; + GList *supported_extension_IDs; + int tc_display; + char *tc_display_content_type; + GList *tc_display_png_characteristics; + char *title; + char *description; + char *icon; +} fido_authenticator_s; + +void _free_fido_asm_authenticator(fido_authenticator_s *data); +void _free_fido_asm_authenticator_list_item(gpointer data); + +typedef struct _fido_asm_reg_in { + char *app_id; + char *user_name; + char *final_challenge; + int attestation_type; +}_fido_asm_reg_in_t; + +void _free_fido_asm_reg_in(_fido_asm_reg_in_t *data); + +typedef struct _fido_asm_transaction { + char *content_type; + char *content; + _fido_asm_display_png_characteristics_descriptor_t *display_charac; +}_fido_asm_transaction_t; + +void _free_fido_asm_transaction(_fido_asm_transaction_t *data); + +typedef struct _fido_asm_auth_in { + char *app_id; + GList *key_ids; + char *final_challenge; + GList *trans_list;//_fido_asm_transaction_t list +}_fido_asm_auth_in_t; + +void _free_fido_asm_auth_in(_fido_asm_auth_in_t *data); + +typedef struct _fido_asm_dereg_in { + char *app_id; + char *key_id; +}_fido_asm_dereg_in_t; + +void _free_fido_asm_dereg_in(_fido_asm_dereg_in_t *data); + +/* client sends list of this type to ui adaptor*/ +typedef struct _ui_auth_data { + char *asm_id; + char *auth_index; + char *label; + int att_type; +} _ui_auth_data_t; + +void _free_ui_auth_data(_ui_auth_data_t *data); + +typedef struct _auth_reg_assertion { + char *assertion_schm; + char *assertion; + //GList *tc_disp_char_list; + //GList *ext_list; +} _auth_reg_assertion_t; + +void _free_auth_reg_assertion(_auth_reg_assertion_t *data); +void _free_auth_reg_assertion_list_item(gpointer data); + +typedef enum { + _ASM_OUT_TYPE_MIN = -1, + _ASM_OUT_TYPE_REG, + _ASM_OUT_TYPE_AUTH, + _ASM_OUT_TYPE_MAX +}_asm_out_type_e; + +typedef struct _asm_out { + int status_code; + _asm_out_type_e type; + void *response_data;/*type can be : _asm_reg_out_t, _asm_auth_out_t*/ + GList *ext_list; +}_asm_out_t; + +void _free_asm_out(_asm_out_t *data); + +typedef struct _asm_reg_out { + char *assertion; + char *assertion_schm; +} _asm_reg_out_t; + +void _free_asm_reg_out(_asm_reg_out_t *data); + +typedef struct _asm_auth_out { + char *assertion; + char *assertion_scheme; +} _asm_auth_out_t; + +void _free_asm_auth_out(_asm_auth_out_t *data); + +typedef struct _matched_auth_data { + char *asm_id; + char *auth_index; + int att_type; + char *label; + GList *key_ids; +} _matched_auth_data_t; + +void _free_matched_auth_data(gpointer data); + +typedef struct _matched_auth_dereg { + char *asm_id; + char *auth_index; + char *app_id; + char *key_id; +} _matched_auth_dereg_t; + +void _free_matched_auth_dereg(_matched_auth_dereg_t *data); + +typedef struct _asm_dereg_out { + int status_code; /* 0 signifies success.*/ +} _asm_dereg_out_t; + +typedef struct _asm_app_reg { + char *app_id; + GList *key_id_list; +} _asm_app_reg_t; + +void _free_asm_app_reg(_asm_app_reg_t *data); + +typedef struct _asm_get_reg_out { + int status_code; + GList *app_reg_list;/*_asm_app_reg_t list*/ +} _asm_get_reg_out_t; + +void _free_asm_get_reg_out(_asm_get_reg_out_t *data); + +typedef struct _dereg_q { + GQueue *dereg_asm_in_q; + void *cb_data; +} _dereg_q_t; + +typedef void (*_fido_discover_asm_cb) (int tz_error_code, int fido_error_code, GList *asm_auth_info_list, void *user_data); + +typedef struct __attribute__((packed)) _tlv { + uint16_t type; + uint16_t len; + uint8_t *val; +} _tlv_t; + +void _free_tlv(_tlv_t *data); + +typedef struct _auth_reg_assertion_tlv { + char *aaid; + unsigned char *key_id; + int key_id_len; +}_auth_reg_assertion_tlv_t; + +void _free_auth_reg_assertion_tlv(_auth_reg_assertion_tlv_t *data); + +typedef struct _response_ { + _op_header_t *header; + char *fcp; + GList *assertion_list; +}_response_t; + +void _free_response(_response_t *data); + +typedef enum { + _DBUS_OP_TYPE_INIT, + _DBUS_OP_TYPE_DE_INIT, + _DBUS_OP_TYPE_DISCOVER, + _DBUS_OP_TYPE_CHECK_POLICY, + _DBUS_OP_TYPE_PROCESS, + _DBUS_OP_TYPE_NOTIFY +} _dbus_op_type_e; + +typedef enum { + _ASM_STATUS_OK = 0x00, + _ASM_STATUS_ERROR = 0x01, + _ASM_STATUS_ACCESS_DENIED = 0x02, + _ASM_STATUS_USER_CANCELLED = 0x03 +} _asm_status_e; + +void _free_tc_disp_png_char(gpointer data); + +void _free_asm_auth_list(gpointer data); + +#define _CLIENT_VENDOR_NAME_MAX_SIZE 127 +#define _CLIENT_VENDOR_NAME "samsung" +#define _CLIENT_VERSION_MAJOR 1 +#define _CLIENT_VERSION_MINOR 0 + +#define _VERSION_MAJOR 1 +#define _VERSION_MINOR 0 + +#define _INVALID_INT -1 + +#define _GET_INFO_ASM_REQUEST_JSON "{\"asmVersion\":{\"major\":1,\"minor\":0},\"requestType\":\"GetInfo\"}" + +#define UI_DATA_ASM_ID "asm_id" +#define UI_DATA_AUTH_INDEX "auth" +#define UI_DATA_LABEL "label" +#define UI_DATA_ATT_TYPE "att" + +#define _FIDO_DBUS_NAME "org.tizen.fido" +#define _FIDO_DBUS_PATH "/org/tizen/fido" + +#define _FIDO_NO_CHANNEL_BINDING_DBUS_STRING "empty_channel_binding" +#define _FIDO_CID_KEY_UNUSED "unused" + +#define _DBUS_TIMEOUT_INFINITE G_MAXINT +#define _DBUS_TIMEOUT_USE_DEFAULT -1 + +#define _EMPTY_JSON_STRING "{}" + +#define _UI_IPC_KEY_REQ "ui_rq" + +#define _UI_SVC_PACKAGE "org.tizen.fidosvcui" +#define _UI_SVC_BIN_PATH "/usr/apps/org.tizen.fidosvcui/bin/org.tizen.fidosvcui" + +#endif // FIDO_INTERNAL_TYPES_H diff --git a/common/fido_json_handler.c b/common/fido_json_handler.c new file mode 100644 index 0000000..dfedb05 --- /dev/null +++ b/common/fido_json_handler.c @@ -0,0 +1,2280 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#include +#include +#include +#include +#include +#if !GLIB_CHECK_VERSION (2, 31, 0) +#include +#endif +#include +#include "fido_internal_types.h" +#include "fido_json_handler.h" +#include "fido_keys.h" +#include "fido_logs.h" +#include "fido_uaf_types.h" +#include "fido_b64_util.h" +#include "fido_tlv_util.h" + +/*JSON keys start*/ +#define _JSON_KEY_ID "id" +#define _JSON_KEY_DATA "data" +#define _JSON_KEY_FAIL_IF_UNKNOWN "fail_if_unknown" +#define _JSON_KEY_EXTS "exts" +#define _JSON_KEY_UPV "upv" +#define _JSON_KEY_MAJOR "major" +#define _JSON_KEY_MINOR "minor" +#define _JSON_KEY_OP "op" +#define _JSON_KEY_APPID "appID" +#define _JSON_KEY_SERVER_DATA "serverData" +#define _JSON_KEY_AAID "aaid" +#define _JSON_KEY_VENDOR_ID "vendorID" +#define _JSON_KEY_KEY_IDS "keyIDs" +#define _JSON_KEY_USER_VERIFICATION "userVerification" +#define _JSON_KEY_KEY_PROTECTION "keyProtection" +#define _JSON_KEY_MATCHER_PROTECTION "matcherProtection" +#define _JSON_KEY_ATTACHMENT_HINT "attachmentHint" +#define _JSON_KEY_TC_DISPLAY "tcDisplay" +#define _JSON_KEY_AUTH_ALGOS "authenticationAlgorithms" +#define _JSON_KEY_AUTH_ALGO "authenticationAlgorithm" +#define _JSON_KEY_ASSERT_SCHEMES "assertionSchemes" +#define _JSON_KEY_ATT_TYPES "attestationTypes" +#define _JSON_KEY_ATT_TYPE "attestationType" +#define _JSON_KEY_AUTH_VERSION "authenticatorVersion" +#define _JSON_KEY_PLTE "plte" +#define _JSON_KEY_R "r" +#define _JSON_KEY_G "g" +#define _JSON_KEY_B "b" +#define _JSON_KEY_WIDTH "width" +#define _JSON_KEY_HEIGHT "height" +#define _JSON_KEY_BIT_DEPTH "bitDepth" +#define _JSON_KEY_COLOR_TYPE "colorType" +#define _JSON_KEY_COMPRESSION "compression" +#define _JSON_KEY_FILTER "filter" +#define _JSON_KEY_INTERLACE "interlace" +#define _JSON_KEY_TC_DISP_PNG_CHARS "tcDisplayPNGCharacteristics" +#define _JSON_KEY_RESP_DATA "responseData" +#define _JSON_KEY_AUTHENTICATORS "Authenticators" +#define _JSON_KEY_AUTHENTICATORS_SMALL "authenticators" +#define _JSON_KEY_AUTH_INDEX "authenticatorIndex" +#define _JSON_KEY_IS_USER_ENROLLED "isUserEnrolled" +#define _JSON_KEY_HAS_SETTINGS "hasSettings" +#define _JSON_KEY_AAID "aaid" +#define _JSON_KEY_IS_2_FACTOR_ONLY "isSecondFactorOnly" +#define _JSON_KEY_IS_ROAMING_AUTH "isRoamingAuthenticator" +#define _JSON_KEY_SUPPORTED_EXT_IDS "supportedExtensionIDs" +#define _JSON_KEY_TC_DISP_CONTENT_TYPE "tcDisplayContentType" +#define _JSON_KEY_TITLE "title" +#define _JSON_KEY_DESC "description" +#define _JSON_KEY_ICON "icon" +#define _JSON_KEY_STATUS_CODE "statusCode" +#define _JSON_KEY_ASSERTION "assertion" +#define _JSON_KEY_ASSERT_SCHEME "assertionScheme" +#define _JSON_KEY_CHALLENGE "challenge" +#define _JSON_KEY_CH_BINDING "channelBinding" +#define _JSON_KEY_SERVER_END_POINT "serverEndPoint" +#define _JSON_KEY_TLS_SERVER_CERT "tlsServerCertificate" +#define _JSON_KEY_TLS_UNIQUE "tlsUnique" +#define _JSON_KEY_CID_PUB_KEY "cid_pubkey" +#define _JSON_KEY_FACET_ID "facetID" +#define _JSON_KEY_HEADER "header" +#define _JSON_KEY_FC_PARAMS "fcParams" +#define _JSON_KEY_FINAL_CHALLENGE "finalChallenge" +#define _JSON_KEY_ASSERTIONS "assertions" +#define _JSON_KEY_POLICY "policy" +#define _JSON_KEY_ACCEPTED "accepted" +#define _JSON_KEY_DISALLOWED "disallowed" +#define _JSON_KEY_USER_NAME "username" +#define _JSON_KEY_TRUSTED_FACETS "trustedFacets" +#define _JSON_KEY_VERSION "version" +#define _JSON_KEY_IDS "ids" +#define _JSON_KEY_APP_REGS "appRegs" +#define _JSON_KEY_REQ_TYPE "requestType" +#define _JSON_KEY_KEY_ID "keyID" +#define _JSON_KEY_TRANSACTION "transaction" +#define _JSON_KEY_CONTENT_TYPE "contentType" +#define _JSON_KEY_CONTENT "content" +#define _JSON_KEY_REGISTER "Register" +#define _JSON_KEY_AUTHENTICATE "Authenticate" +#define _JSON_KEY_DEREGISTER "Deregister" +#define _JSON_KEY_ASM_VERSION "asmVersion" +#define _JSON_KEY_GET_REGS "GetRegistrations" +#define _JSON_KEY_KTY "kty" +#define _JSON_KEY_CRV "crv" +#define _JSON_KEY_X "x" +#define _JSON_KEY_Y "y" +#define _JSON_KEY_ARGS "args" + +#define _JSON_KEY_VENDOR "vendor" +#define _JSON_KEY_BIN_PATH "bin_path" +#define _JSON_KEY_DBUS_INFO "dbus_info" +#define _JSON_KEY_DBUS_OBJ_PATH "dbus_obj_path" +#define _JSON_KEY_DBUS_INTF_NAME "dbus_interface_name" +#define _JSON_KEY_DBUS_METHOD_NAME "dbus_method_name" +/*JSON keys end*/ + +static void +__add_string_to_json_object(JsonBuilder *json_obj, const char *key, const char *val) +{ + if (key == NULL || val == NULL) + return; + + json_builder_set_member_name(json_obj, key); + json_builder_add_string_value(json_obj, val); +} + +static void +__add_int_to_json_object(JsonBuilder *json_obj, const char *key, int val) +{ + if (key == NULL || val == _INVALID_INT) + return; + + json_builder_set_member_name(json_obj, key); + json_builder_add_int_value(json_obj, val); +} + +static char* +__get_string_from_json_object(JsonObject *obj, const char *key) +{ + _INFO("__get_string_from_json_object [%s]", key); + + if (json_object_has_member(obj, key) == false) + return NULL; + + const char *str = json_object_get_string_member(obj, key); + _INFO("[%s] = [%s]", key, str); + + return strdup(str); +} + +static int +__get_int_from_json_object(JsonObject *obj, const char *key) +{ + if (obj == NULL) + return _INVALID_INT; + + if (json_object_has_member(obj, key) == false) + return _INVALID_INT; + + int int_val = json_object_get_int_member(obj, key); + dlog_print(DLOG_INFO, "FIDO", "[%s] = [%d]", key, int_val); + + return int_val; +} + +static _extension_t * +__get_extension(JsonObject *ext_json_obj) +{ + RET_IF_FAIL(ext_json_obj != NULL, NULL); + + _extension_t *ext = (_extension_t*) calloc(1, sizeof(_extension_t)); + RET_IF_FAIL(ext != NULL, NULL); + + ext->id = __get_string_from_json_object(ext_json_obj, _JSON_KEY_ID); + ext->data = __get_string_from_json_object(ext_json_obj, _JSON_KEY_DATA); + ext->fail_if_unknown = json_object_get_boolean_member(ext_json_obj, _JSON_KEY_FAIL_IF_UNKNOWN); + + return ext; + +} + +static GList * +__get_extension_list(JsonObject *root_obj) +{ + RET_IF_FAIL(root_obj != NULL, NULL); + + JsonArray *ext_json_arr = json_object_get_array_member(root_obj, _JSON_KEY_EXTS); + RET_IF_FAIL(ext_json_arr != NULL, NULL); + + int ext_arr_len = json_array_get_length(ext_json_arr); + RET_IF_FAIL(ext_arr_len > 0, NULL); + + GList *ext_list = NULL; + + int i = 0; + for (; i < ext_arr_len; i++) { + JsonObject *ext_json_obj = json_array_get_object_element(ext_json_arr, i); + if (ext_json_obj != NULL) { + _extension_t *ext = __get_extension(ext_json_obj); + if (ext != NULL) + ext_list = g_list_append(ext_list, ext); + } + } + + return ext_list; +} + +static _op_header_t* +__parse_uaf_header(JsonObject *header_obj) +{ + _INFO("__parse_uaf_header"); + + _op_header_t *header = (_op_header_t *)calloc(1, sizeof(_op_header_t)); + + header->version = (_version_t *)calloc(1, sizeof(_version_t)); + + JsonObject *ver_obj = json_object_get_object_member(header_obj, _JSON_KEY_UPV); + if (ver_obj == NULL) { + _free_op_header(header); + return NULL; + } + + int major = __get_int_from_json_object(ver_obj, _JSON_KEY_MAJOR); + int minor = __get_int_from_json_object(ver_obj, _JSON_KEY_MINOR); + + if (major == _INVALID_INT || minor == _INVALID_INT) { + + _free_op_header(header); + return NULL; + } + + _INFO("found valid version"); + + header->version->major = major; + header->version->minor = minor; + + header->operation = __get_string_from_json_object(header_obj, _JSON_KEY_OP); + + header->app_id = __get_string_from_json_object(header_obj, _JSON_KEY_APPID); + + header->server_data = __get_string_from_json_object(header_obj, _JSON_KEY_SERVER_DATA); + + header->ext_list = __get_extension_list(header_obj); + + return header; +} + +static GList * +__get_string_list_from_json_array(JsonArray *json_arr) +{ + if (json_arr == NULL) + return NULL; + + GList *list = NULL; + + int arr_len = json_array_get_length(json_arr); + int i = 0; + for (; i < arr_len; i++) { + const char *str = json_array_get_string_element(json_arr, i); + if (str != NULL) + list = g_list_append(list, strdup(str)); + + } + + return list; +} + +static GList * +__get_int_list_from_json_array(JsonArray *json_arr) +{ + if (json_arr == NULL) + return NULL; + + GList *list = NULL; + + int arr_len = json_array_get_length(json_arr); + int i = 0; + for (; i < arr_len; i++) { + int val = json_array_get_int_element(json_arr, i); + list = g_list_append(list, GINT_TO_POINTER(val)); + + } + + return list; +} + +static _match_criteria_t* +_uaf_parser_parse_match(JsonObject *match_obj) +{ + _INFO("_uaf_parser_parse_match"); + + if (match_obj != NULL) { + + _match_criteria_t *match_criteria = (_match_criteria_t*)calloc(1, sizeof(_match_criteria_t)); + + JsonArray *aaid_arr = json_object_get_array_member(match_obj, _JSON_KEY_AAID); + if (aaid_arr != NULL) { + match_criteria->aaid_list = __get_string_list_from_json_array(aaid_arr); + } + + JsonArray *vendor_arr = json_object_get_array_member(match_obj, _JSON_KEY_VENDOR_ID); + if (vendor_arr != NULL) { + match_criteria->vendor_list = __get_string_list_from_json_array(vendor_arr); + } + + JsonArray *key_id_arr = json_object_get_array_member(match_obj, _JSON_KEY_KEY_IDS); + if (key_id_arr != NULL) { + match_criteria->key_id_list = __get_string_list_from_json_array(key_id_arr); + } + + match_criteria->user_verification = __get_int_from_json_object(match_obj, _JSON_KEY_USER_VERIFICATION); + + match_criteria->key_protection = __get_int_from_json_object(match_obj, _JSON_KEY_KEY_PROTECTION); + + match_criteria->matcher_protection = __get_int_from_json_object(match_obj, _JSON_KEY_MATCHER_PROTECTION); + + match_criteria->attachement_hint = __get_int_from_json_object(match_obj, _JSON_KEY_ATTACHMENT_HINT); + + match_criteria->tc_display = __get_int_from_json_object(match_obj, _JSON_KEY_TC_DISPLAY); + + + JsonArray *auth_algo_arr = json_object_get_array_member(match_obj, _JSON_KEY_AUTH_ALGOS); + if (auth_algo_arr) { + match_criteria->auth_algo_list = __get_int_list_from_json_array(auth_algo_arr); + } + + JsonArray *assertion_schm_arr = json_object_get_array_member(match_obj, _JSON_KEY_ASSERT_SCHEMES); + if (assertion_schm_arr) { + match_criteria->assertion_scheme_list = __get_string_list_from_json_array(assertion_schm_arr); + } + + JsonArray *att_type_arr = json_object_get_array_member(match_obj, _JSON_KEY_ATT_TYPES); + if (att_type_arr) { + match_criteria->attestation_type_list = __get_string_list_from_json_array(att_type_arr); + } + + match_criteria->auth_version = __get_int_from_json_object(match_obj, _JSON_KEY_AUTH_VERSION); + + _INFO("_uaf_parser_parse_match is returning match_criteria"); + + return match_criteria; + } + + _INFO("_uaf_parser_parse_match is returning NULL"); + return NULL; +} + +static GList* +__get_plte_list(JsonObject *png_json_obj) +{ + + _INFO(""); + + GList *plte_list_priv = NULL; + + JsonArray *plte_json_arr = json_object_get_array_member(png_json_obj, "plte"); + RET_IF_FAIL(plte_json_arr != NULL, NULL); + + int plte_arr_len = json_array_get_length(plte_json_arr); + RET_IF_FAIL(plte_arr_len > 0, NULL); + + int i = 0; + for (; i < plte_arr_len; i++) { + JsonObject *plte_json_obj = json_array_get_object_element(plte_json_arr, i); + if (plte_json_obj != NULL) { + fido_rgb_pallette_entry_s *pallete = + (fido_rgb_pallette_entry_s *) calloc(1, sizeof(fido_rgb_pallette_entry_s)); + + if (pallete != NULL) { + pallete->r = __get_int_from_json_object(plte_json_obj, _JSON_KEY_R); + pallete->g = __get_int_from_json_object(plte_json_obj, _JSON_KEY_G); + pallete->b = __get_int_from_json_object(plte_json_obj, _JSON_KEY_B); + + plte_list_priv = g_list_append(plte_list_priv, pallete); + } + + } + } + + if (plte_list_priv == NULL) + return NULL; + + plte_list_priv = g_list_first(plte_list_priv); + + _INFO(""); + + return plte_list_priv; +} + +static fido_display_png_characteristics_descriptor_s * +__get_png_data(JsonObject *png_json_obj) +{ + RET_IF_FAIL(png_json_obj != NULL, NULL); + + _INFO(""); + + fido_display_png_characteristics_descriptor_s *png_data = (fido_display_png_characteristics_descriptor_s*) + calloc(1, sizeof(fido_display_png_characteristics_descriptor_s)); + + png_data->width = __get_int_from_json_object(png_json_obj, _JSON_KEY_WIDTH); + png_data->height = __get_int_from_json_object(png_json_obj, _JSON_KEY_HEIGHT); + png_data->bit_depth = __get_int_from_json_object(png_json_obj, _JSON_KEY_BIT_DEPTH); + png_data->color_type = __get_int_from_json_object(png_json_obj, _JSON_KEY_COLOR_TYPE); + png_data->compression = __get_int_from_json_object(png_json_obj, _JSON_KEY_COMPRESSION); + png_data->filter = __get_int_from_json_object(png_json_obj, _JSON_KEY_FILTER); + png_data->interlace = __get_int_from_json_object(png_json_obj, _JSON_KEY_INTERLACE); + + png_data->plte = __get_plte_list(png_json_obj); + + _INFO(""); + return png_data; +} + +static GList * +__get_tc_disp_png_array(JsonObject *auth_obj) +{ + RET_IF_FAIL(auth_obj != NULL, NULL); + + JsonArray *png_arr_json = json_object_get_array_member(auth_obj, _JSON_KEY_TC_DISP_PNG_CHARS); + RET_IF_FAIL(png_arr_json != NULL, NULL); + + int arr_len = json_array_get_length(png_arr_json); + RET_IF_FAIL(arr_len > 0, NULL); + + GList *png_list = NULL; + int i = 0; + for (; i < arr_len; i++) { + JsonObject *png_json_obj = json_array_get_object_element(png_arr_json, i); + if (png_json_obj != NULL) { + + fido_display_png_characteristics_descriptor_s *png = __get_png_data(png_json_obj); + if (png != NULL) + png_list = g_list_append(png_list, png); + } + } + + + return png_list; +} + +GList* +_uaf_parser_parse_asm_response_discover_client(char **asm_response_list, int len, int *error_code) +{ + _INFO("_uaf_parser_parse_asm_response_discover start"); + + RET_IF_FAIL(asm_response_list != NULL, NULL); + + GList *available_authenticators = NULL; + + int i = 0; + for (; i < len; i++) { + + JsonParser *parser = json_parser_new(); + CATCH_IF_FAIL(parser != NULL); + + GError *parse_err = NULL; + json_parser_load_from_data(parser, asm_response_list[i], -1, &parse_err); + CATCH_IF_FAIL(parse_err == NULL); + + JsonNode *root = json_parser_get_root(parser); + CATCH_IF_FAIL(root != NULL); + + JsonObject *root_obj = json_node_get_object(root); + CATCH_IF_FAIL(root_obj != NULL); + + int err_temp = 0; + err_temp = json_object_get_int_member(root_obj, _JSON_KEY_STATUS_CODE); + + *error_code = err_temp; + CATCH_IF_FAIL(*error_code == 0); + + JsonObject *response_obj = json_object_get_object_member(root_obj, _JSON_KEY_RESP_DATA); + CATCH_IF_FAIL(response_obj != NULL); + + JsonArray *auth_arr = json_object_get_array_member(response_obj, _JSON_KEY_AUTHENTICATORS); + CATCH_IF_FAIL(auth_arr != NULL); + + int auth_arr_len = json_array_get_length(auth_arr); + + int auth_arr_index = 0; + for (auth_arr_index = 0; auth_arr_index < auth_arr_len; auth_arr_index++) { + JsonObject *auth_obj = json_array_get_object_element(auth_arr, auth_arr_index); + if (auth_obj != NULL) { + fido_authenticator_s *auth_info = (fido_authenticator_s *)calloc(1, sizeof(fido_authenticator_s)); + + + int auth_index = json_object_get_int_member(auth_obj, _JSON_KEY_AUTH_INDEX); + char *auth_idx_str = (char*)calloc(1, 128); + snprintf(auth_idx_str, 127, "%d", auth_index); + + auth_info->auth_index = auth_idx_str; + _INFO("auth_info->auth_index = [%s]", auth_info->auth_index); + + + /* FIXME : ASM version list */ + + bool is_enrolled = json_object_get_boolean_member(auth_obj, _JSON_KEY_IS_USER_ENROLLED); + auth_info->is_user_enrolled = is_enrolled; + + bool has_settings = json_object_get_boolean_member(auth_obj, _JSON_KEY_HAS_SETTINGS); + auth_info->has_settings = has_settings; + + + const char *aaid = json_object_get_string_member(auth_obj, _JSON_KEY_AAID); + if (aaid != NULL) { + auth_info->aaid = strdup(aaid); + _INFO("auth_info->aaid = [%s]", auth_info->aaid); + } + + + const char *assertion_schm = json_object_get_string_member(auth_obj, _JSON_KEY_ASSERT_SCHEME); + if (assertion_schm != NULL) + auth_info->assertion_scheme = strdup(assertion_schm); + + int auth_algo = json_object_get_int_member(auth_obj, _JSON_KEY_AUTH_ALGO); + auth_info->authentication_algorithm = auth_algo; + + GList *att_list = NULL; + JsonArray *att_arr = json_object_get_array_member(auth_obj, _JSON_KEY_ATT_TYPES); + if (att_arr != NULL) { + int att_arr_len = json_array_get_length(att_arr); + int att_arr_idx = 0; + for (att_arr_idx = 0; att_arr_idx < att_arr_len; att_arr_idx++) { + int att = json_array_get_int_element(att_arr, att_arr_idx); + att_list = g_list_append(att_list, GINT_TO_POINTER(att)); + } + } + + if (att_list != NULL) + auth_info->attestation_types = g_list_first(att_list); + + int user_verification = json_object_get_int_member(auth_obj, _JSON_KEY_USER_VERIFICATION); + auth_info->user_verification = user_verification; + + int key_prot = json_object_get_int_member(auth_obj, _JSON_KEY_KEY_PROTECTION); + auth_info->key_protection = key_prot; + + + int matcher_prot = json_object_get_int_member(auth_obj, _JSON_KEY_MATCHER_PROTECTION); + auth_info->matcher_protection = matcher_prot; + + int attch_hint = json_object_get_int_member(auth_obj, _JSON_KEY_ATTACHMENT_HINT); + auth_info->attachment_hint = attch_hint; + + + bool is_sec_only = json_object_get_boolean_member(auth_obj, _JSON_KEY_IS_2_FACTOR_ONLY); + auth_info->is_second_factor_only = is_sec_only; + + + bool is_roaming = json_object_get_boolean_member(auth_obj, _JSON_KEY_IS_ROAMING_AUTH); + auth_info->is_roaming = is_roaming; + + + JsonArray *ext_id_json_arr = json_object_get_array_member(auth_obj, _JSON_KEY_SUPPORTED_EXT_IDS); + if (ext_id_json_arr != NULL) + auth_info->supported_extension_IDs = __get_string_list_from_json_array(ext_id_json_arr); + + + int tc_disp = json_object_get_int_member(auth_obj, _JSON_KEY_TC_DISPLAY); + auth_info->tc_display = tc_disp; + + const char *tc_dis_type = json_object_get_string_member(auth_obj, _JSON_KEY_TC_DISP_CONTENT_TYPE); + if (tc_dis_type != NULL) + auth_info->tc_display_content_type = strdup(tc_dis_type); + + + auth_info->tc_display_png_characteristics = __get_tc_disp_png_array(auth_obj); + + const char *title = json_object_get_string_member(auth_obj, _JSON_KEY_TITLE); + if (title != NULL) + auth_info->title = strdup(title); + + + const char *desc = json_object_get_string_member(auth_obj, _JSON_KEY_DESC); + if (desc != NULL) + auth_info->description = strdup(desc); + + + const char *icon = json_object_get_string_member(auth_obj, _JSON_KEY_ICON); + if (icon != NULL) + auth_info->icon = strdup(icon); + + /* Supported UAF versions is fixed to 1.0*/ + fido_version_s *version = calloc(1, sizeof(fido_version_s)); + version->major = _VERSION_MAJOR; + version->minor = _VERSION_MINOR; + + auth_info->supported_versions = g_list_append(auth_info->supported_versions, version); + + available_authenticators = g_list_append(available_authenticators, auth_info); + } + } + + if (parser != NULL) + g_object_unref(parser); + + } + + + available_authenticators = g_list_first(available_authenticators); + + _INFO("available_authenticators count = [%d]", g_list_length(available_authenticators)); + + return available_authenticators; + +CATCH: + return NULL; +} + +GList* +_uaf_parser_parse_asm_response_discover(GList *asm_response_list, int *error_code) +{ + _INFO("_uaf_parser_parse_asm_response_discover start"); + + RET_IF_FAIL(asm_response_list != NULL, NULL); + + GList *available_authenticators = NULL; + + GList *asm_response_list_iter = g_list_first(asm_response_list); + while (asm_response_list_iter != NULL) { + + _asm_discover_response_t *asm_resp = (_asm_discover_response_t*)(asm_response_list_iter->data); + if (asm_resp->error_code == FIDO_ERROR_NONE + && + asm_resp->asm_response_json != NULL) { + + JsonParser *parser = json_parser_new(); + CATCH_IF_FAIL(parser != NULL); + + GError *parse_err = NULL; + json_parser_load_from_data(parser, asm_resp->asm_response_json, -1, &parse_err); + CATCH_IF_FAIL(parse_err == NULL); + + JsonNode *root = json_parser_get_root(parser); + CATCH_IF_FAIL(root != NULL); + + JsonObject *root_obj = json_node_get_object(root); + CATCH_IF_FAIL(root_obj != NULL); + + int err_temp = 0; + err_temp = json_object_get_int_member(root_obj, _JSON_KEY_STATUS_CODE); + + *error_code = err_temp; + CATCH_IF_FAIL(*error_code == 0); + + JsonObject *response_obj = json_object_get_object_member(root_obj, _JSON_KEY_RESP_DATA); + CATCH_IF_FAIL(response_obj != NULL); + + JsonArray *auth_arr = json_object_get_array_member(response_obj, _JSON_KEY_AUTHENTICATORS); + CATCH_IF_FAIL(auth_arr != NULL); + + int auth_arr_len = json_array_get_length(auth_arr); + + int auth_arr_index = 0; + for (auth_arr_index = 0; auth_arr_index < auth_arr_len; auth_arr_index++) { + JsonObject *auth_obj = json_array_get_object_element(auth_arr, auth_arr_index); + if (auth_obj != NULL) { + fido_authenticator_s *auth_info = (fido_authenticator_s *)calloc(1, sizeof(fido_authenticator_s)); + + + int auth_index = json_object_get_int_member(auth_obj, _JSON_KEY_AUTH_INDEX); + char *auth_idx_str = (char*)calloc(1, 128); + snprintf(auth_idx_str, 127, "%d", auth_index); + + auth_info->auth_index = auth_idx_str; + _INFO("auth_info->auth_index = [%s]", auth_info->auth_index); + + + /* FIXME : ASM version list */ + + bool is_enrolled = json_object_get_boolean_member(auth_obj, _JSON_KEY_IS_USER_ENROLLED); + auth_info->is_user_enrolled = is_enrolled; + + bool has_settings = json_object_get_boolean_member(auth_obj, _JSON_KEY_HAS_SETTINGS); + auth_info->has_settings = has_settings; + + + const char *aaid = json_object_get_string_member(auth_obj, _JSON_KEY_AAID); + if (aaid != NULL) + auth_info->aaid = strdup(aaid); + + + const char *assertion_schm = json_object_get_string_member(auth_obj, _JSON_KEY_ASSERT_SCHEME); + if (assertion_schm != NULL) + auth_info->assertion_scheme = strdup(assertion_schm); + + int auth_algo = json_object_get_int_member(auth_obj, _JSON_KEY_AUTH_ALGO); + auth_info->authentication_algorithm = auth_algo; + + GList *att_list = NULL; + JsonArray *att_arr = json_object_get_array_member(auth_obj, _JSON_KEY_ATT_TYPES); + if (att_arr != NULL) { + int att_arr_len = json_array_get_length(att_arr); + int att_arr_idx = 0; + for (att_arr_idx = 0; att_arr_idx < att_arr_len; att_arr_idx++) { + int att = json_array_get_int_element(att_arr, att_arr_idx); + att_list = g_list_append(att_list, GINT_TO_POINTER(att)); + } + } + + if (att_list != NULL) + auth_info->attestation_types = g_list_first(att_list); + + int user_verification = json_object_get_int_member(auth_obj, _JSON_KEY_USER_VERIFICATION); + auth_info->user_verification = user_verification; + + int key_prot = json_object_get_int_member(auth_obj, _JSON_KEY_KEY_PROTECTION); + auth_info->key_protection = key_prot; + + + int matcher_prot = json_object_get_int_member(auth_obj, _JSON_KEY_MATCHER_PROTECTION); + auth_info->matcher_protection = matcher_prot; + + int attch_hint = json_object_get_int_member(auth_obj, _JSON_KEY_ATTACHMENT_HINT); + auth_info->attachment_hint = attch_hint; + + + bool is_sec_only = json_object_get_boolean_member(auth_obj, _JSON_KEY_IS_2_FACTOR_ONLY); + auth_info->is_second_factor_only = is_sec_only; + + + bool is_roaming = json_object_get_boolean_member(auth_obj, _JSON_KEY_IS_ROAMING_AUTH); + auth_info->is_roaming = is_roaming; + + + JsonArray *ext_id_json_arr = json_object_get_array_member(auth_obj, _JSON_KEY_SUPPORTED_EXT_IDS); + if (ext_id_json_arr != NULL) + auth_info->supported_extension_IDs = __get_string_list_from_json_array(ext_id_json_arr); + + + int tc_disp = json_object_get_int_member(auth_obj, _JSON_KEY_TC_DISPLAY); + auth_info->tc_display = tc_disp; + + const char *tc_dis_type = json_object_get_string_member(auth_obj, _JSON_KEY_TC_DISP_CONTENT_TYPE); + if (tc_dis_type != NULL) + auth_info->tc_display_content_type = strdup(tc_dis_type); + + + auth_info->tc_display_png_characteristics = __get_tc_disp_png_array(auth_obj); + + const char *title = json_object_get_string_member(auth_obj, _JSON_KEY_TITLE); + if (title != NULL) + auth_info->title = strdup(title); + + + const char *desc = json_object_get_string_member(auth_obj, _JSON_KEY_DESC); + if (desc != NULL) + auth_info->description = strdup(desc); + + + const char *icon = json_object_get_string_member(auth_obj, _JSON_KEY_ICON); + if (icon != NULL) + auth_info->icon = strdup(icon); + + + if (asm_resp->asm_id != NULL) + auth_info->asm_id = strdup(asm_resp->asm_id); + else + _ERR("Authenticator does not have ASM ID!!"); + + available_authenticators = g_list_append(available_authenticators, auth_info); + } + } + + if (parser != NULL) + g_object_unref(parser); + + } + + asm_response_list_iter = g_list_next(asm_response_list_iter); + + } + + + available_authenticators = g_list_first(available_authenticators); + + _INFO("available_authenticators count = [%d]", g_list_length(available_authenticators)); + + return available_authenticators; + +CATCH: + return NULL; +} + +_asm_out_t* +_uaf_parser_parse_asm_response_reg(const char *asm_response_json, int *error_code) +{ + _asm_out_t *asm_out = NULL; + int status = 0; + GError *parser_err = NULL; + + JsonParser *parser = json_parser_new(); + bool is_success = json_parser_load_from_data(parser, asm_response_json, -1, &parser_err); + + CATCH_IF_FAIL(is_success == true); + + JsonNode *root = json_parser_get_root(parser); + CATCH_IF_FAIL(root != NULL); + + JsonObject *root_obj = json_node_get_object(root); + CATCH_IF_FAIL(root_obj != NULL); + + status = json_object_get_int_member(root_obj, _JSON_KEY_STATUS_CODE); + CATCH_IF_FAIL(status == 0); + + JsonObject *resp_obj = json_object_get_object_member(root_obj, _JSON_KEY_RESP_DATA); + CATCH_IF_FAIL(resp_obj != NULL); + + const char *assertion = json_object_get_string_member(resp_obj, _JSON_KEY_ASSERTION); + CATCH_IF_FAIL(assertion != NULL); + + const char *assertion_scheme = json_object_get_string_member(resp_obj, _JSON_KEY_ASSERT_SCHEME); + CATCH_IF_FAIL(assertion_scheme != NULL); + + _asm_reg_out_t *reg_out = (_asm_reg_out_t*)calloc(1, sizeof(_asm_reg_out_t)); + reg_out->assertion = strdup(assertion); + reg_out->assertion_schm = strdup(assertion_scheme); + + asm_out = (_asm_out_t*)calloc(1, sizeof(_asm_out_t)); + asm_out->type = _ASM_OUT_TYPE_REG; + + asm_out->status_code = status; + asm_out->response_data = reg_out; + + asm_out->ext_list = __get_extension_list(root_obj); + + if (parser != NULL) + g_object_unref(parser); + + *error_code = 0; + return asm_out; + +CATCH: + _free_asm_out(asm_out); + if (parser != NULL) + g_object_unref(parser); + + *error_code = status; + return NULL; +} + +_asm_out_t* +_uaf_parser_parse_asm_response_auth(const char *asm_response_json, int *error_code) +{ + _asm_out_t *asm_out = NULL; + int status = 0; + GError *parser_err = NULL; + + JsonParser *parser = json_parser_new(); + bool is_success = json_parser_load_from_data(parser, asm_response_json, -1, &parser_err); + + CATCH_IF_FAIL(is_success == true); + + JsonNode *root = json_parser_get_root(parser); + CATCH_IF_FAIL(root != NULL); + + JsonObject *root_obj = json_node_get_object(root); + CATCH_IF_FAIL(root_obj != NULL); + + status = json_object_get_int_member(root_obj, _JSON_KEY_STATUS_CODE); + CATCH_IF_FAIL(status == 0); + + JsonObject *resp_obj = json_object_get_object_member(root_obj, _JSON_KEY_RESP_DATA); + CATCH_IF_FAIL(resp_obj != NULL); + + const char *assertion = json_object_get_string_member(resp_obj, _JSON_KEY_ASSERTION); + CATCH_IF_FAIL(assertion != NULL); + + const char *assertion_scheme = json_object_get_string_member(resp_obj, _JSON_KEY_ASSERT_SCHEME); + CATCH_IF_FAIL(assertion_scheme != NULL); + + _asm_auth_out_t *auth_out = (_asm_auth_out_t*)calloc(1, sizeof(_asm_auth_out_t)); + auth_out->assertion = strdup(assertion); + auth_out->assertion_scheme = strdup(assertion_scheme); + + asm_out = (_asm_out_t*)calloc(1, sizeof(_asm_out_t)); + asm_out->type = _ASM_OUT_TYPE_AUTH; + + asm_out->status_code = status; + asm_out->response_data = auth_out; + + asm_out->ext_list = __get_extension_list(root_obj); + + if (parser != NULL) + g_object_unref(parser); + + *error_code = 0; + return asm_out; + +CATCH: + _free_asm_out(asm_out); + if (parser != NULL) + g_object_unref(parser); + + *error_code = status; + return NULL; +} + +_asm_dereg_out_t* +_uaf_parser_parse_asm_response_dereg(const char *asm_response_json, int *error_code) +{ + _asm_dereg_out_t *asm_out = NULL; + int status = 0; + GError *parser_err = NULL; + + JsonParser *parser = json_parser_new(); + bool is_success = json_parser_load_from_data(parser, asm_response_json, -1, &parser_err); + + CATCH_IF_FAIL(is_success == true); + + JsonNode *root = json_parser_get_root(parser); + CATCH_IF_FAIL(root != NULL); + + JsonObject *root_obj = json_node_get_object(root); + CATCH_IF_FAIL(root_obj != NULL); + + asm_out = (_asm_dereg_out_t*)calloc(1, sizeof(_asm_dereg_out_t)); + + asm_out->status_code = json_object_get_int_member(root_obj, _JSON_KEY_STATUS_CODE); + + if (parser != NULL) + g_object_unref(parser); + + *error_code = 0; + return asm_out; + +CATCH: + free(asm_out); + if (parser != NULL) + g_object_unref(parser); + + *error_code = status; + return NULL; +} + +int +_uaf_composer_compose_asm_reg_request(_version_t *version, int auth_index, _fido_asm_reg_in_t *reg_in, char **asm_reg_json) +{ + _INFO("_uaf_composer_compose_asm_reg_request start"); + + /*Builder start*/ + JsonBuilder *builder = json_builder_new(); + json_builder_begin_object(builder); + + /*requestType*/ + __add_string_to_json_object(builder, _JSON_KEY_REQ_TYPE, _JSON_KEY_REGISTER); + + /*authIndex*/ + json_builder_set_member_name(builder, _JSON_KEY_AUTH_INDEX); + json_builder_add_int_value(builder, auth_index); + + /*version*/ + json_builder_set_member_name(builder, _JSON_KEY_ASM_VERSION); + json_builder_begin_object(builder); + json_builder_set_member_name(builder, _JSON_KEY_MAJOR); + json_builder_add_int_value(builder, version->major); + + json_builder_set_member_name(builder, _JSON_KEY_MINOR); + json_builder_add_int_value(builder, version->minor); + + json_builder_end_object(builder); + /*version*/ + + /*args*/ + json_builder_set_member_name(builder, _JSON_KEY_ARGS); + json_builder_begin_object(builder); + + __add_string_to_json_object(builder, _JSON_KEY_APPID, reg_in->app_id); + __add_string_to_json_object(builder, _JSON_KEY_USER_NAME, reg_in->user_name); + __add_string_to_json_object(builder, _JSON_KEY_FINAL_CHALLENGE, reg_in->final_challenge); + + if (reg_in->attestation_type != _INVALID_INT) { + json_builder_set_member_name(builder, _JSON_KEY_ATT_TYPE); + + json_builder_add_int_value(builder, reg_in->attestation_type); + } + + + json_builder_end_object(builder); + /*args*/ + + + json_builder_end_object(builder); + /*Builder end*/ + + JsonGenerator *gen = json_generator_new(); + JsonNode *root_builder = json_builder_get_root(builder); + json_generator_set_root(gen, root_builder); + + json_node_free(root_builder); + g_object_unref(builder); + + gsize len = 0; + char *json = json_generator_to_data(gen, &len); + if (json != NULL) { + *asm_reg_json = json; + + if (gen != NULL) + g_object_unref(gen); + + _INFO("%s", json); + + _INFO("_uaf_composer_compose_asm_reg_request end"); + + return 0; + } + + g_object_unref(gen); + + _INFO("_uaf_composer_compose_asm_reg_request fail"); + return -1; +} + +int +_uaf_composer_compose_asm_auth_request(_version_t *version, int auth_index, _fido_asm_auth_in_t *auth_in, + char **asm_auth_json) +{ + _INFO("_uaf_composer_compose_asm_auth_request start"); + + /*Builder start*/ + JsonBuilder *builder = json_builder_new(); + json_builder_begin_object(builder); + + /*requestType*/ + __add_string_to_json_object(builder, _JSON_KEY_REQ_TYPE, _JSON_KEY_AUTHENTICATE); + + /*authIndex*/ + json_builder_set_member_name(builder, _JSON_KEY_AUTH_INDEX); + json_builder_add_int_value(builder, auth_index); + + /*version*/ + json_builder_set_member_name(builder, _JSON_KEY_ASM_VERSION); + json_builder_begin_object(builder); + json_builder_set_member_name(builder, _JSON_KEY_MAJOR); + json_builder_add_int_value(builder, version->major); + + json_builder_set_member_name(builder, _JSON_KEY_MINOR); + json_builder_add_int_value(builder, version->minor); + + json_builder_end_object(builder); + /*version*/ + + /*args*/ + json_builder_set_member_name(builder, _JSON_KEY_ARGS); + json_builder_begin_object(builder); + + __add_string_to_json_object(builder, _JSON_KEY_APPID, auth_in->app_id); + __add_string_to_json_object(builder, _JSON_KEY_FINAL_CHALLENGE, auth_in->final_challenge); + + if (auth_in->key_ids != NULL) { + _INFO("keyID to be sent in ASM req"); + /*keyIDs*/ + json_builder_set_member_name(builder, _JSON_KEY_KEY_IDS); + json_builder_begin_array(builder); + + GList *iter = g_list_first(auth_in->key_ids); + while (iter != NULL) { + + char *val = (char*)(iter->data); + json_builder_add_string_value(builder, val); + iter = iter->next; + } + json_builder_end_array(builder); + /*keyIDs*/ + } + + /*Transaction list composing*/ + if (auth_in->trans_list != NULL) { + /*transaction*/ + json_builder_set_member_name(builder, _JSON_KEY_TRANSACTION); + json_builder_begin_array(builder); + + GList *iter = g_list_first(auth_in->trans_list); + while (iter != NULL) { + + _fido_asm_transaction_t *val = (_fido_asm_transaction_t*)(iter->data); + /*transaction array element*/ + json_builder_begin_object(builder); + + /*contentType*/ + __add_string_to_json_object(builder, _JSON_KEY_CONTENT_TYPE, val->content_type); + /*content*/ + __add_string_to_json_object(builder, _JSON_KEY_CONTENT, val->content); + /*tcDisplayPNGCharacteristics*/ + if (val->display_charac != NULL) { + + __add_int_to_json_object(builder, _JSON_KEY_WIDTH, val->display_charac->width); + __add_int_to_json_object(builder, _JSON_KEY_HEIGHT, val->display_charac->height); + __add_int_to_json_object(builder, _JSON_KEY_BIT_DEPTH, val->display_charac->bit_depth); + __add_int_to_json_object(builder, _JSON_KEY_COLOR_TYPE, val->display_charac->color_type); + __add_int_to_json_object(builder, _JSON_KEY_COMPRESSION, val->display_charac->compression); + __add_int_to_json_object(builder, _JSON_KEY_FILTER, val->display_charac->filter); + __add_int_to_json_object(builder, _JSON_KEY_INTERLACE, val->display_charac->interlace); + __add_int_to_json_object(builder, _JSON_KEY_WIDTH, val->display_charac->width); + + /*plte*/ + if (val->display_charac->plte != NULL) { + + json_builder_begin_array(builder); + + GList *plte_iter = g_list_first(val->display_charac->plte); + while (plte_iter != NULL) { + _fido_asm_rgb_pallette_entry_t *plte = (_fido_asm_rgb_pallette_entry_t*)(plte_iter->data); + + __add_int_to_json_object(builder, _JSON_KEY_R, plte->r); + __add_int_to_json_object(builder, _JSON_KEY_G, plte->g); + __add_int_to_json_object(builder, _JSON_KEY_B, plte->b); + + plte_iter = plte_iter->next; + } + + json_builder_end_array(builder); + } + } + + json_builder_end_object(builder); + + iter = iter->next; + } + json_builder_end_array(builder); + /*transaction*/ + } + + json_builder_end_object(builder); + /*args*/ + + + json_builder_end_object(builder); + /*Builder end*/ + + JsonGenerator *gen = json_generator_new(); + JsonNode *root_builder = json_builder_get_root(builder); + json_generator_set_root(gen, root_builder); + + json_node_free(root_builder); + g_object_unref(builder); + + gsize len = 0; + char *json = json_generator_to_data(gen, &len); + if (json != NULL) { + *asm_auth_json = json; + + if (gen != NULL) + g_object_unref(gen); + + _INFO("%s", json); + + _INFO("_uaf_composer_compose_asm_auth_request end"); + + return 0; + } + + g_object_unref(gen); + + _INFO("_uaf_composer_compose_asm_auth_request fail"); + return -1; +} + +int +_uaf_composer_compose_asm_dereg_request(_version_t *version, int auth_index, _matched_auth_dereg_t *dereg_in, + char **asm_dereg_json) +{ + _INFO("_uaf_composer_compose_asm_dereg_request start"); + + /*Builder start*/ + JsonBuilder *builder = json_builder_new(); + JsonBuilder *root = json_builder_begin_object(builder); + + /*requestType*/ + __add_string_to_json_object(root, _JSON_KEY_REQ_TYPE, _JSON_KEY_DEREGISTER); + + /*authIndex*/ + json_builder_set_member_name(root, _JSON_KEY_AUTH_INDEX); + json_builder_add_int_value(root, auth_index); + + /*version*/ + json_builder_set_member_name(root, _JSON_KEY_ASM_VERSION); + JsonBuilder *ver_root = json_builder_begin_object(root); + json_builder_set_member_name(ver_root, _JSON_KEY_MAJOR); + json_builder_add_int_value(ver_root, version->major); + + json_builder_set_member_name(ver_root, _JSON_KEY_MINOR); + json_builder_add_int_value(ver_root, version->minor); + + json_builder_end_object(ver_root); + + + /*args*/ + json_builder_set_member_name(root, _JSON_KEY_ARGS); + JsonBuilder *args_root = json_builder_begin_object(root); + + __add_string_to_json_object(args_root, _JSON_KEY_APPID, dereg_in->app_id); + __add_string_to_json_object(args_root, _JSON_KEY_KEY_ID, dereg_in->key_id); + + json_builder_end_object(args_root); + + json_builder_end_object(root); + /*Builder end*/ + + JsonGenerator *gen = json_generator_new(); + JsonNode *root_builder = json_builder_get_root(builder); + json_generator_set_root(gen, root_builder); + + json_node_free(root_builder); + g_object_unref(builder); + + gsize len = 0; + char *json = json_generator_to_data(gen, &len); + if (json != NULL) { + *asm_dereg_json = json; + _INFO("_uaf_composer_compose_uaf_process_response_reg return success"); + + if (gen != NULL) + g_object_unref(gen); + + _INFO("%s", json); + + _INFO("_uaf_composer_compose_asm_dereg_request end"); + + return 0; + } + + g_object_unref(gen); + + _INFO("_uaf_composer_compose_asm_dereg_request fail"); + return -1; + +} + +//{"appID":"https://qa-egypt.noknoktest.com:443/UAFSampleProxy/uaf/facets.uaf","challenge":"uYBuGQf7r-LND16Q0GUpPRi112UjCtcym3awjm-MmmI","channelBinding":{},"facetID":"com.noknok.android.sampleapp"} +char * +_uaf_composer_compose_final_challenge(const char *app_id, const char *challenge, const char *facet_id, const char *ch_bin) +{ + _INFO("_uaf_composer_compose_final_challenge"); + + JsonBuilder *builder = json_builder_new(); + json_builder_begin_object(builder); + + __add_string_to_json_object(builder, _JSON_KEY_APPID, app_id); + + __add_string_to_json_object(builder, _JSON_KEY_CHALLENGE, challenge); + + json_builder_set_member_name(builder, _JSON_KEY_CH_BINDING); + json_builder_begin_object(builder); + if (ch_bin != NULL) { + + JsonParser *chb_parser = json_parser_new(); + + GError *chb_err = NULL; + bool chb_parsed = json_parser_load_from_data(chb_parser, ch_bin, -1, &chb_err); + if (chb_parsed == FALSE) { + return NULL; + } + + JsonNode *chb_root = json_parser_get_root(chb_parser); + RET_IF_FAIL(chb_root != NULL, NULL); + + JsonObject *chb_root_obj = json_node_get_object(chb_root); + RET_IF_FAIL(chb_root_obj != NULL, NULL); + + char *end_pt = __get_string_from_json_object(chb_root_obj, _JSON_KEY_SERVER_END_POINT); + char *cert = __get_string_from_json_object(chb_root_obj, _JSON_KEY_TLS_SERVER_CERT); + char *uni = __get_string_from_json_object(chb_root_obj, _JSON_KEY_TLS_UNIQUE); + char *cid = __get_string_from_json_object(chb_root_obj, _JSON_KEY_CID_PUB_KEY); + + __add_string_to_json_object(builder, _JSON_KEY_SERVER_END_POINT, end_pt); + __add_string_to_json_object(builder, _JSON_KEY_TLS_SERVER_CERT, cert); + __add_string_to_json_object(builder, _JSON_KEY_TLS_UNIQUE, uni); + __add_string_to_json_object(builder, _JSON_KEY_CID_PUB_KEY, cid); + + SAFE_DELETE(end_pt); + SAFE_DELETE(cert); + SAFE_DELETE(uni); + SAFE_DELETE(cid); + + g_object_unref(chb_parser); + + } + + /*If no channledbinding to add, putting empty */ + json_builder_end_object(builder); + + __add_string_to_json_object(builder, _JSON_KEY_FACET_ID, facet_id); + + json_builder_end_object(builder); + + JsonNode *root_node = json_builder_get_root(builder); + + JsonGenerator *generator = json_generator_new(); + json_generator_set_root(generator, root_node); + + json_node_free(root_node); + g_object_unref(builder); + + char *json_str = NULL; + gsize len = 0; + json_str = json_generator_to_data(generator, &len); + + if (json_str == NULL) + return NULL; + + int inlen = strlen(json_str); + int fc_enc_len = (4 * ((inlen + 2) / 3)) + 1; + + unsigned char *fc_enc = calloc(1, fc_enc_len); + + int r = _fido_b64url_encode((unsigned char*)json_str, inlen, fc_enc, &fc_enc_len); + + _INFO("_fido_b64url_encode len=[%d]", fc_enc_len); + + SAFE_DELETE(json_str); + g_object_unref(generator); + + if (r != 0) + return NULL; + + _INFO("_fido_b64url_encoded string=%s", fc_enc); + + return ((char*)fc_enc); + +} + +int +_uaf_composer_compose_uaf_process_response_reg(_op_header_t *header, char *final_ch, GList *assertions, char **uaf_response) +{ + _INFO("_uaf_composer_compose_uaf_process_response_reg"); + + RET_IF_FAIL(header != NULL, FIDO_ERROR_PROTOCOL_ERROR); + + /*Only 1.0 protocol support*/ + + JsonBuilder *builder = json_builder_new(); + + json_builder_begin_array(builder); + + json_builder_begin_object(builder); + + /* header*/ + json_builder_set_member_name(builder, _JSON_KEY_HEADER); + json_builder_begin_object(builder); + + json_builder_set_member_name(builder, _JSON_KEY_APPID); + json_builder_add_string_value(builder, header->app_id); + + json_builder_set_member_name(builder, _JSON_KEY_OP); + json_builder_add_string_value(builder, header->operation); + + json_builder_set_member_name(builder, _JSON_KEY_SERVER_DATA); + json_builder_add_string_value(builder, header->server_data); + + json_builder_set_member_name(builder, _JSON_KEY_UPV); + json_builder_begin_object(builder); + + json_builder_set_member_name(builder, _JSON_KEY_MAJOR); + json_builder_add_int_value(builder, header->version->major); + + json_builder_set_member_name(builder, _JSON_KEY_MINOR); + json_builder_add_int_value(builder, header->version->minor); + + json_builder_end_object(builder); + + json_builder_end_object(builder); + + /* fcparams*/ + if (final_ch != NULL) { + json_builder_set_member_name(builder, _JSON_KEY_FC_PARAMS); + json_builder_add_string_value(builder, final_ch); + } + + /* assertions*/ + json_builder_set_member_name(builder, _JSON_KEY_ASSERTIONS); + json_builder_begin_array(builder); + GList *assertions_iter = g_list_first(assertions); + while (assertions_iter != NULL) { + _auth_reg_assertion_t *ass_data = (_auth_reg_assertion_t*)(assertions_iter->data); + json_builder_begin_object(builder); + json_builder_set_member_name(builder, _JSON_KEY_ASSERTION); + json_builder_add_string_value(builder, ass_data->assertion); + + json_builder_set_member_name(builder, _JSON_KEY_ASSERT_SCHEME); + json_builder_add_string_value(builder, ass_data->assertion_schm); + + json_builder_end_object(builder); + + assertions_iter = assertions_iter->next; + + } + + json_builder_end_array(builder); + + json_builder_end_object(builder); + + + json_builder_end_array(builder); + + + JsonNode *root_builder = json_builder_get_root(builder); + + JsonGenerator *gen = json_generator_new(); + json_generator_set_root(gen, root_builder); + + json_node_free(root_builder); + g_object_unref(builder); + + gsize len = 0; + char *json = json_generator_to_data(gen, &len); + if (json != NULL) { + *uaf_response = json; + _INFO("_uaf_composer_compose_uaf_process_response_reg return success"); + + if (gen != NULL) + g_object_unref(gen); + + return FIDO_ERROR_NONE; + } + + _INFO("_uaf_composer_compose_uaf_process_response_reg return fail"); + g_object_unref(gen); + return FIDO_ERROR_PROTOCOL_ERROR; +} + +int +_uaf_composer_compose_uaf_process_response_auth(_op_header_t *header, char *final_ch, GList *assertions, char **uaf_response) +{ + return _uaf_composer_compose_uaf_process_response_reg(header, final_ch, assertions, uaf_response); +} + +char * +_uaf_composer_compose_dereg_request(_response_t *uaf_res) +{ + _INFO("_uaf_composer_compose_dereg_request"); + + /*Only 1.0 protocol support*/ + + JsonBuilder *builder = json_builder_new(); + + JsonBuilder *root_array = json_builder_begin_array(builder); + + JsonBuilder *uaf_1_root = json_builder_begin_object(root_array); + + /* header*/ + json_builder_set_member_name(uaf_1_root, _JSON_KEY_HEADER); + JsonBuilder *header_root = json_builder_begin_object(uaf_1_root); + + json_builder_set_member_name(header_root, _JSON_KEY_APPID); + json_builder_add_string_value(header_root, uaf_res->header->app_id); + + json_builder_set_member_name(header_root, _JSON_KEY_OP); + json_builder_add_string_value(header_root, strdup(_UAF_OPERATION_NAME_KEY_DE_REG)); + + json_builder_set_member_name(header_root, _JSON_KEY_SERVER_DATA); + json_builder_add_string_value(header_root, uaf_res->header->server_data); + + json_builder_set_member_name(header_root, _JSON_KEY_UPV); + JsonBuilder *upv_root = json_builder_begin_object(header_root); + + json_builder_set_member_name(upv_root, _JSON_KEY_MAJOR); + json_builder_add_int_value(upv_root, uaf_res->header->version->major); + + json_builder_set_member_name(upv_root, _JSON_KEY_MINOR); + json_builder_add_int_value(upv_root,uaf_res->header->version->minor); + + json_builder_end_object(upv_root); + + json_builder_end_object(header_root); + /* header*/ + + _INFO("after header"); + + + /*appID*/ + if (uaf_res->header->app_id == NULL) { + _ERR("appID is missing"); + + g_object_unref(builder); + return NULL; + } + + json_builder_set_member_name(uaf_1_root, _JSON_KEY_APPID); + json_builder_add_string_value(uaf_1_root, uaf_res->header->app_id); + /*appID*/ + + + /*authenticators*/ + json_builder_set_member_name(uaf_1_root, _JSON_KEY_AUTHENTICATORS_SMALL); + JsonBuilder *auth_root = json_builder_begin_array(uaf_1_root); + GList *assertions_iter = g_list_first(uaf_res->assertion_list); + while (assertions_iter != NULL) { + + _auth_reg_assertion_t *ass_data = (_auth_reg_assertion_t*)(assertions_iter->data); + + char *assrt = ass_data->assertion; + + _INFO("%s", assrt); + + _auth_reg_assertion_tlv_t *assrt_tlv = _tlv_util_decode_reg_assertion(assrt); + if (assrt_tlv == NULL) { + _ERR("Invalid assertion format"); + + g_object_unref(builder); + return NULL; + } + + char *aaid = strdup(assrt_tlv->aaid); + + JsonBuilder *obj = json_builder_begin_object(auth_root); + + if (aaid != NULL) { + json_builder_set_member_name(obj, _JSON_KEY_AAID); + json_builder_add_string_value(obj, aaid); + _INFO("aaid=[%s]", aaid); + } + + if (assrt_tlv->key_id != NULL) { + int inlen = assrt_tlv->key_id_len; + int enc_len = (4 * ((inlen + 2) / 3)) + 1; + + unsigned char *key_id_enc = calloc(1, enc_len); + + int r = _fido_b64url_encode(assrt_tlv->key_id, inlen, key_id_enc, &enc_len); + + _INFO("_fido_b64url_encode len=[%d]", enc_len); + + if ((key_id_enc != NULL) && (r == 0)) { + _INFO("_fido_b64url_encoded string=%s", key_id_enc); + json_builder_set_member_name(obj, _JSON_KEY_KEY_ID); + json_builder_add_string_value(obj, (char *)key_id_enc); + _INFO("keyid=[%s]", key_id_enc); + } + + } + + _INFO("after assertions"); + + _free_auth_reg_assertion_tlv(assrt_tlv); + + json_builder_end_object(obj); + + + assertions_iter = assertions_iter->next; + + } + + json_builder_end_array(auth_root); + /*authenticators*/ + + + json_builder_end_object(uaf_1_root); + + + json_builder_end_array(root_array); + + + JsonNode *root_builder = json_builder_get_root(builder); + JsonGenerator *gen = json_generator_new(); + json_generator_set_root(gen, root_builder); + + json_node_free(root_builder); + g_object_unref(builder); + + gsize len = 0; + char *dereg_json = json_generator_to_data(gen, &len); + g_object_unref(gen); + + if (dereg_json != NULL) { + _INFO("_uaf_composer_compose_dereg_request return success"); + _INFO("%s", dereg_json); + return dereg_json; + } + + _INFO("_uaf_composer_compose_dereg_request return fail"); + return NULL; +} + +static _policy_t* +__get_policy(JsonObject *uaf_object) +{ + /*TODO : Check in spec whether accepted array can be NULL, i.e allow all?*/ + + JsonObject *policy_obj = json_object_get_object_member(uaf_object, _JSON_KEY_POLICY); + RET_IF_FAIL(policy_obj != NULL, NULL); + + JsonArray *accepted_array = json_object_get_array_member(policy_obj, _JSON_KEY_ACCEPTED); + RET_IF_FAIL(accepted_array != NULL, NULL); + + int accepted_len = json_array_get_length(accepted_array); + _INFO("Parser accepted list count [%d]", accepted_len); + + _policy_t *policy_info = (_policy_t *)calloc(1, sizeof(_policy_t)); + policy_info->is_keyid_present = false; + + GList *allowed_list = NULL; + + int i = 0; + for (i = 0; i < accepted_len; i++) { + + JsonArray *accepted_arr_inner = json_array_get_array_element(accepted_array, i); + if (accepted_arr_inner) { + int accepted_len_inner = json_array_get_length(accepted_arr_inner); + _INFO("Parser accepted list inner count [%d]", accepted_len_inner); + + int j = 0; + for (j = 0; j < accepted_len_inner; j++) { + GList *allowed_list_inner = NULL; + + JsonObject *match_obj = json_array_get_object_element(accepted_arr_inner, j); + if (match_obj) { + _match_criteria_t *match_info = _uaf_parser_parse_match(match_obj); + if (match_info) { + _INFO("Appending match_info"); + if (policy_info->is_keyid_present == false) { + if (match_info->key_id_list != NULL) + policy_info->is_keyid_present = true; + } + allowed_list_inner = g_list_append(allowed_list_inner, match_info); + } + } + if (j == (accepted_len_inner - 1)) { + if (allowed_list_inner) { + _INFO("Appending accepted list"); + allowed_list = g_list_append(allowed_list, allowed_list_inner); + } + } + } + } + } + + if (allowed_list != NULL) + policy_info->accepted_list = g_list_first(allowed_list); + + GList *disallowed_list = NULL; + + JsonArray *disallowed_array = json_object_get_array_member(policy_obj, _JSON_KEY_DISALLOWED); + if (disallowed_array != NULL) { + int disallowed_len = json_array_get_length(disallowed_array); + + for (i = 0; i < disallowed_len; i++) { + JsonObject *match_obj = json_array_get_object_element(disallowed_array, i); + if (match_obj) { + + _match_criteria_t *match_info = _uaf_parser_parse_match(match_obj); + if (match_info) { + if (policy_info->is_keyid_present == false) { + if (match_info->key_id_list != NULL) + policy_info->is_keyid_present = true; + } + disallowed_list = g_list_append(disallowed_list, match_info); + } + } + } + + if (disallowed_list != NULL) + policy_info->disallowed_list = g_list_first(disallowed_list); + } + + _INFO("returning policy [%p]", policy_info); + return policy_info; +} + +static _reg_request_t* +__parse_uaf_reg_message(JsonObject *uaf_object) +{ + _reg_request_t *reg_req_temp = (_reg_request_t *)calloc(1, sizeof(_reg_request_t)); + + reg_req_temp->challenge = __get_string_from_json_object(uaf_object, _JSON_KEY_CHALLENGE); + + reg_req_temp->user_name = __get_string_from_json_object(uaf_object, _JSON_KEY_USER_NAME); + + reg_req_temp->policy = __get_policy(uaf_object); + if (reg_req_temp->policy != NULL) + _INFO("parsed policy [%p]", reg_req_temp->policy); + else + _INFO("parsed policy [NULL]"); + + return reg_req_temp; +} + +static GList* +__get_transaction_list(JsonObject *uaf_obj) +{ + RET_IF_FAIL(uaf_obj != NULL, NULL); + + JsonArray *tr_arr = json_object_get_array_member(uaf_obj, _JSON_KEY_TRANSACTION); + RET_IF_FAIL(tr_arr != NULL, NULL); + + _INFO(""); + + GList *trans_list = NULL; + + int tr_arr_len = json_array_get_length(tr_arr); + int i = 0; + for (; i< tr_arr_len; i++) { + JsonObject *tr_obj = json_array_get_object_element(tr_arr, i); + if (tr_obj != NULL) { + + _auth_transaction_t *trans = calloc(1, sizeof(_auth_transaction_t)); + + trans->content_type = __get_string_from_json_object(tr_obj, _JSON_KEY_CONTENT_TYPE); + trans->content = __get_string_from_json_object(tr_obj, _JSON_KEY_CONTENT); + + /*tcDisplayPNGCharacteristics*/ + JsonObject *tc_disp_obj = json_object_get_object_member(tr_obj, _JSON_KEY_TC_DISP_PNG_CHARS); + if (tc_disp_obj != NULL) { + trans->display_charac = __get_png_data(tr_obj); + } + + trans_list = g_list_append(trans_list, trans); + } + } + + if (trans_list != NULL) { + trans_list = g_list_first(trans_list); + _INFO("Transaction list count = [%d]", g_list_length(trans_list)); + } + + _INFO(""); + return trans_list; +} + +static _auth_request_t* +__parse_uaf_auth_message(JsonObject *uaf_object) +{ + _auth_request_t *auth_req_temp = (_auth_request_t *)calloc(1, sizeof(_auth_request_t)); + + auth_req_temp->challenge = __get_string_from_json_object(uaf_object, _JSON_KEY_CHALLENGE); + + auth_req_temp->transaction_list = __get_transaction_list(uaf_object); + + auth_req_temp->policy = __get_policy(uaf_object); + + if (auth_req_temp->policy != NULL) + _INFO("parsed policy [%p]", auth_req_temp->policy); + else + _INFO("parsed policy [NULL]"); + + return auth_req_temp; +} + +static void +__dereg_auth_parser(JsonArray *array, guint index_, JsonNode *element_node, gpointer user_data) +{ + _dereg_request_t *dereg_req_temp = (_dereg_request_t *)user_data; + + JsonObject *auth_obj = json_node_get_object(element_node); + if (auth_obj != NULL) { + _dereg_auth_info_t *dereg_auth = (_dereg_auth_info_t*)calloc(1, sizeof(_dereg_auth_info_t)); + + dereg_auth->aaid = __get_string_from_json_object(auth_obj, _JSON_KEY_AAID); + dereg_auth->key_id = __get_string_from_json_object(auth_obj, _JSON_KEY_KEY_ID); + + dereg_req_temp->auth_info_list = g_list_append(dereg_req_temp->auth_info_list, dereg_auth); + } +} + +static _dereg_request_t* +__parse_uaf_dereg_message(JsonObject *uaf_object) +{ + _dereg_request_t *dereg_req_temp = (_dereg_request_t *)calloc(1, sizeof(_dereg_request_t)); + + JsonArray *auth_arr = json_object_get_array_member(uaf_object, _JSON_KEY_AUTHENTICATORS_SMALL); + if (auth_arr != NULL) { + json_array_foreach_element(auth_arr, __dereg_auth_parser, dereg_req_temp); + } + + return dereg_req_temp; +} + +_message_t * +_uaf_parser_parse_message(const char *uaf_json, const gchar *channel_binding) +{ + _INFO("_uaf_parser_parse_message"); + + RET_IF_FAIL(uaf_json != NULL, NULL); + + _message_t *uaf_message_temp = (_message_t*) calloc(1, sizeof(_message_t)); + uaf_message_temp->type = _MESSAGE_TYPE_MIN; + + if (channel_binding != NULL) { + if (strcmp(channel_binding, _FIDO_NO_CHANNEL_BINDING_DBUS_STRING) != 0) + uaf_message_temp->channel_binding = strdup(channel_binding); + } + + JsonParser *parser = json_parser_new(); + CATCH_IF_FAIL(parser != NULL); + + GError *parse_err = NULL; + json_parser_load_from_data(parser, uaf_json, -1, &parse_err); + CATCH_IF_FAIL(parse_err == NULL); + + JsonNode *root = json_parser_get_root(parser); + CATCH_IF_FAIL(root != NULL); + + JsonArray *uaf_array = json_node_get_array(root); + CATCH_IF_FAIL(uaf_array != NULL); + + /* Parse all and accept only 1.0 version */ + + int uaf_arr_len = json_array_get_length(uaf_array); + if (uaf_arr_len <= 0) { + _ERR("No UAF message found"); + + _free_message(uaf_message_temp); + g_object_unref(parser); + return NULL; + } + + int i = 0; + for (; i < uaf_arr_len ; i++) { + JsonObject *uaf_object = json_array_get_object_element(uaf_array, i); + CATCH_IF_FAIL(uaf_object != NULL); + + JsonObject *header_obj = json_object_get_object_member(uaf_object, _JSON_KEY_HEADER); + CATCH_IF_FAIL(header_obj != NULL); + + uaf_message_temp->header = __parse_uaf_header(header_obj); + + /* NULL signifies the header version is not 1.0 */ + if (uaf_message_temp->header == NULL) + continue; + + if (strcmp(uaf_message_temp->header->operation, _UAF_OPERATION_NAME_KEY_REG) == 0){ + uaf_message_temp->data = (void *)__parse_uaf_reg_message(uaf_object); + if (uaf_message_temp->data == NULL) { + + _free_message(uaf_message_temp); + g_object_unref(parser); + + return NULL; + } + else { + uaf_message_temp->type = _MESSAGE_TYPE_REG; + + g_object_unref(parser); + + return uaf_message_temp; + } + } + + if (strcmp(uaf_message_temp->header->operation, _UAF_OPERATION_NAME_KEY_AUTH) == 0){ + uaf_message_temp->data = (void *)__parse_uaf_auth_message(uaf_object); + if (uaf_message_temp->data == NULL) { + + _free_message(uaf_message_temp); + g_object_unref(parser); + + return NULL; + } + else { + uaf_message_temp->type = _MESSAGE_TYPE_AUTH; + + g_object_unref(parser); + return uaf_message_temp; + + } + } + + if (strcmp(uaf_message_temp->header->operation, _UAF_OPERATION_NAME_KEY_DE_REG) == 0){ + uaf_message_temp->data = (void *)__parse_uaf_dereg_message(uaf_object); + if (uaf_message_temp->data == NULL) { + + _free_message(uaf_message_temp); + g_object_unref(parser); + + return NULL; + } + else { + uaf_message_temp->type = _MESSAGE_TYPE_DEREG; + + g_object_unref(parser); + return uaf_message_temp; + } + } + + } + +CATCH: + _free_message(uaf_message_temp); + if (parser != NULL) + g_object_unref(parser); + + return NULL; +} + +GList * +_uaf_parser_parse_trusted_facets(const char *json) +{ + JsonParser *parser = json_parser_new(); + + gsize len = -1; + GError *err = NULL; + + GList *app_id_list = NULL; + + bool is_parsed = json_parser_load_from_data(parser, json, len, &err); + CATCH_IF_FAIL(is_parsed == TRUE); + + + JsonNode *root = json_parser_get_root(parser); + + JsonObject *root_obj = json_node_get_object(root); + CATCH_IF_FAIL(root_obj != NULL); + + JsonArray *facet_arr = json_object_get_array_member(root_obj, _JSON_KEY_TRUSTED_FACETS); + CATCH_IF_FAIL(facet_arr != NULL); + + int facet_arr_len = json_array_get_length(facet_arr); + + int i = 0; + for (; i < facet_arr_len; i++) { + JsonObject *facet_obj = json_array_get_object_element(facet_arr, i); + if (facet_obj != NULL) { + + JsonObject *ver_obj = json_object_get_object_member(facet_obj, _JSON_KEY_VERSION); + if (ver_obj != NULL) { + int major = _INVALID_INT; + int minor = _INVALID_INT; + + major = json_object_get_int_member(ver_obj, _JSON_KEY_MAJOR); + minor = json_object_get_int_member(ver_obj, _JSON_KEY_MINOR); + + if (major == _VERSION_MAJOR && minor == _VERSION_MINOR) { + JsonArray *id_arr = json_object_get_array_member(facet_obj, _JSON_KEY_IDS); + if (id_arr != NULL) { + int id_arr_len = json_array_get_length(id_arr); + + int idx = 0; + for (; idx < id_arr_len; idx++) { + const char *id = json_array_get_string_element(id_arr, idx); + if (id != NULL) { + app_id_list = g_list_append(app_id_list, strdup(id)); + } + } + } + } + } + } + } + +CATCH: + if (parser != NULL) + g_object_unref(parser); + + if (app_id_list != NULL) + app_id_list = g_list_first(app_id_list); + + return app_id_list; +} + +_response_t* +_uaf_parser_parse_uaf_response(const char *uaf_response) +{ + RET_IF_FAIL(uaf_response != NULL, NULL); + + _response_t *uaf_res_temp = (_response_t*) calloc(1, sizeof(_response_t)); + + JsonParser *parser = json_parser_new(); + CATCH_IF_FAIL(parser != NULL); + + GError *parse_err = NULL; + json_parser_load_from_data(parser, uaf_response, -1, &parse_err); + CATCH_IF_FAIL(parse_err == NULL); + + JsonNode *root = json_parser_get_root(parser); + CATCH_IF_FAIL(root != NULL); + + JsonArray *uaf_array = json_node_get_array(root); + CATCH_IF_FAIL(uaf_array != NULL); + + /* Parse all and accept only 1.0 version */ + + int uaf_arr_len = json_array_get_length(uaf_array); + CATCH_IF_FAIL(uaf_arr_len > 0); + + int i = 0; + for (; i < uaf_arr_len ; i++) { + JsonObject *uaf_object = json_array_get_object_element(uaf_array, i); + CATCH_IF_FAIL(uaf_object != NULL); + + JsonObject *header_obj = json_object_get_object_member(uaf_object, _JSON_KEY_HEADER); + CATCH_IF_FAIL(header_obj != NULL); + + uaf_res_temp->header = __parse_uaf_header(header_obj); + + /* NULL signifies the header version is not 1.0 */ + if (uaf_res_temp->header == NULL) + continue; + + char *op = uaf_res_temp->header->operation; + + /*Only process reg and auth responses*/ + if ((strcmp(op, _UAF_OPERATION_NAME_KEY_REG) != 0) + && (strcmp(op, _UAF_OPERATION_NAME_KEY_AUTH) != 0)) { + goto CATCH; + } + + uaf_res_temp->fcp = __get_string_from_json_object(uaf_object, _JSON_KEY_FC_PARAMS); + + JsonArray *assrt_json_arr = json_object_get_array_member(uaf_object, _JSON_KEY_ASSERTIONS); + CATCH_IF_FAIL(assrt_json_arr != NULL); + + int assrt_arr_len = json_array_get_length(assrt_json_arr); + int i = 0; + for (; i < assrt_arr_len; i++) { + JsonObject *assrt_json_obj = json_array_get_object_element(assrt_json_arr, i); + if (assrt_json_obj != NULL) { + + _auth_reg_assertion_t *assrt_data = (_auth_reg_assertion_t*)calloc(1, sizeof(_auth_reg_assertion_t)); + assrt_data->assertion = __get_string_from_json_object(assrt_json_obj, _JSON_KEY_ASSERTION); + assrt_data->assertion_schm = __get_string_from_json_object(assrt_json_obj, _JSON_KEY_ASSERT_SCHEME); + + uaf_res_temp->assertion_list = g_list_append(uaf_res_temp->assertion_list, assrt_data); + + } + } + + } + + g_object_unref(parser); + _INFO("before _uaf_parser_parse_uaf_response end"); + return uaf_res_temp; + +CATCH: + if (parser != NULL) + g_object_unref(parser); + + if (uaf_res_temp != NULL) + _free_response(uaf_res_temp); + + return NULL; +} + +static int +__print_string_list(GList *list) +{ + RET_IF_FAIL(list != NULL, -1); + + GList *list_iter = g_list_first(list); + while (list_iter != NULL) { + char *data = (char*) (list->data); + if (data != NULL) + _INFO("[%s]", data); + + list_iter = list_iter->next; + } + + return 0; +} + +_asm_get_reg_out_t * +_uaf_parser_parser_asm_get_reg_response(const char *get_reg_resp) +{ + _INFO("_uaf_parser_parser_asm_get_reg_response start"); + + RET_IF_FAIL(get_reg_resp != NULL, NULL); + + JsonParser *parser = json_parser_new(); + RET_IF_FAIL(parser != NULL, NULL); + + GError *parser_err = NULL; + gboolean is_parsed = json_parser_load_from_data(parser, get_reg_resp, -1, &parser_err); + RET_IF_FAIL(is_parsed == TRUE, NULL); + + _INFO(""); + + _asm_get_reg_out_t *reg_out = NULL; + + JsonNode *root = json_parser_get_root(parser); + CATCH_IF_FAIL(root != NULL); + + JsonObject *root_obj = json_node_get_object(root); + CATCH_IF_FAIL(root_obj != NULL); + + _INFO(""); + + /*responseData*/ + JsonObject *res_obj = json_object_get_object_member(root_obj, _JSON_KEY_RESP_DATA); + CATCH_IF_FAIL(res_obj != NULL); + + /*appRegs*/ + JsonArray *app_reg_json_arr = json_object_get_array_member(res_obj, _JSON_KEY_APP_REGS); + CATCH_IF_FAIL(app_reg_json_arr != NULL); + + _INFO(""); + + int app_reg_json_arr_len = json_array_get_length(app_reg_json_arr); + CATCH_IF_FAIL(app_reg_json_arr_len > 0); + + reg_out = (_asm_get_reg_out_t*) calloc(1, sizeof(_asm_get_reg_out_t)); + + int i = 0; + for (; i < app_reg_json_arr_len; i++) { + JsonObject *app_reg_json_obj = json_array_get_object_element(app_reg_json_arr, i); + if (app_reg_json_obj != NULL) { + /*appID*/ + const char *app_id = json_object_get_string_member(app_reg_json_obj, _JSON_KEY_APPID); + + _INFO(""); + + /*keyIDs*/ + JsonArray *key_id_json_arr = json_object_get_array_member(app_reg_json_obj, _JSON_KEY_KEY_IDS); + GList *key_id_list = __get_string_list_from_json_array(key_id_json_arr); + + if (app_id != NULL || key_id_list != NULL) { + _asm_app_reg_t *app_reg = (_asm_app_reg_t*) calloc(1, sizeof(_asm_app_reg_t)); + + if (app_id != NULL) { + _INFO("app_id = [%s]", app_id); + app_reg->app_id = strdup(app_id); + } + + app_reg->key_id_list = key_id_list; + __print_string_list(key_id_list); + + reg_out->app_reg_list = g_list_append(reg_out->app_reg_list, app_reg); + _INFO(""); + + } + } + } + + _INFO(""); + /*statusCode*/ + reg_out->status_code = __get_int_from_json_object(root_obj, _JSON_KEY_STATUS_CODE); + +CATCH: + g_object_unref(parser); + + _INFO("_uaf_parser_parser_asm_get_reg_response end"); + return reg_out; +} + +char * +_uaf_composer_compose_get_registrations_request(const char *auth_index) +{ + _INFO("_uaf_composer_compose_get_registrations_request"); + + JsonBuilder *builder = json_builder_new(); + + json_builder_begin_object(builder); + + /*Version : 1.0*/ + json_builder_set_member_name(builder, _JSON_KEY_ASM_VERSION); + json_builder_begin_object(builder); + json_builder_set_member_name(builder, _JSON_KEY_MAJOR); + json_builder_add_int_value(builder, _VERSION_MAJOR); + json_builder_set_member_name(builder, _JSON_KEY_MINOR); + json_builder_add_int_value(builder, _VERSION_MINOR); + json_builder_end_object(builder); + + /*authenticatorIndex*/ + json_builder_set_member_name(builder, _JSON_KEY_AUTH_INDEX); + int auth_index_int = -1; + sscanf(auth_index, "%d", &auth_index_int); + json_builder_add_int_value(builder, auth_index_int); + + + /*requestType : "GetRegistrations" */ + json_builder_set_member_name(builder, _JSON_KEY_REQ_TYPE); + json_builder_add_string_value(builder, _JSON_KEY_GET_REGS); + + + json_builder_end_object(builder); + + JsonNode *root_builder = json_builder_get_root(builder); + JsonGenerator *gen = json_generator_new(); + json_generator_set_root(gen, root_builder); + + json_node_free(root_builder); + g_object_unref(builder); + + gsize len = 0; + char *json = json_generator_to_data(gen, &len); + + if (json != NULL) + _INFO("%s", json); + + g_object_unref(gen); + return json; +} + +int +_convert_asm_status_code_to_uaf_error(int asm_status_code) +{ + switch (asm_status_code) { + + case _ASM_STATUS_OK: + return FIDO_ERROR_NONE; + + case _ASM_STATUS_ERROR: + return FIDO_ERROR_UNKNOWN; + + case _ASM_STATUS_ACCESS_DENIED: + return FIDO_ERROR_PERMISSION_DENIED; + + case _ASM_STATUS_USER_CANCELLED: + return FIDO_ERROR_USER_CANCELLED; + + default: + return FIDO_ERROR_UNKNOWN; + } +} + +/* +{ + "vendor" : "Samsung Electronics", + "bin_path" : "/usr/bin/fido-asm", + "dbus_info" : "org.tizen.fido_uaf_asm.server", + "dbus_obj_path" : "/org/tizen/fido_uaf_asm/server", + "dbus_interface_name" : "org.tizen.fido_uaf_asm.server.interface", + "dbus_method_name" : "asm_request" +} +*/ + +_fido_asm_proxy_t* +_parse_asm_conf_file(const char *file_name) +{ + _INFO("_parse_asm_conf_file"); + + RET_IF_FAIL(file_name != NULL, NULL); + + JsonParser *parser = json_parser_new(); + + _fido_asm_proxy_t *proxy = NULL; + GError *err = NULL; + gboolean is_parsed = json_parser_load_from_file(parser, file_name, &err); + CATCH_IF_FAIL(is_parsed == TRUE); + + JsonNode *root = json_parser_get_root(parser); + CATCH_IF_FAIL(root != NULL); + + JsonObject *root_obj = json_node_get_object(root); + CATCH_IF_FAIL(root_obj != NULL); + + const char *vendor = json_object_get_string_member(root_obj, _JSON_KEY_VENDOR); + CATCH_IF_FAIL(vendor != NULL); + + const char *bin_path = json_object_get_string_member(root_obj, _JSON_KEY_BIN_PATH); + CATCH_IF_FAIL(bin_path != NULL); + + const char *dbus_info = json_object_get_string_member(root_obj, _JSON_KEY_DBUS_INFO); + CATCH_IF_FAIL(dbus_info != NULL); + + const char *dbus_obj_path = json_object_get_string_member(root_obj, _JSON_KEY_DBUS_OBJ_PATH); + CATCH_IF_FAIL(dbus_obj_path != NULL); + + const char *dbus_interface_name = json_object_get_string_member(root_obj, _JSON_KEY_DBUS_INTF_NAME); + CATCH_IF_FAIL(dbus_interface_name != NULL); + + const char *dbus_method_name = json_object_get_string_member(root_obj, _JSON_KEY_DBUS_METHOD_NAME); + CATCH_IF_FAIL(dbus_method_name != NULL); + + proxy = calloc(1, sizeof(_fido_asm_proxy_t)); + + proxy->vendor = strdup(vendor); + proxy->bin_path = strdup(bin_path); + proxy->dbus_info = strdup(dbus_info); + proxy->dbus_obj_path = strdup(dbus_obj_path); + proxy->dbus_interface_name = strdup(dbus_interface_name); + proxy->dbus_method_name = strdup(dbus_method_name); + +CATCH: + g_object_unref(parser); + return proxy; +} diff --git a/common/fido_json_handler.h b/common/fido_json_handler.h new file mode 100644 index 0000000..f6ade12 --- /dev/null +++ b/common/fido_json_handler.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef FIDO_JSON_PARSER_H_ +#define FIDO_JSON_PARSER_H_ + +#include +#include +#include "fido_uaf_types.h" +#include "fido_internal_types.h" + +_message_t *_uaf_parser_parse_message(const char *uaf_json, const gchar *channel_binding); + +/*List of fido_authenticator_s */ +GList* _uaf_parser_parse_asm_response_discover(GList *asm_response_list, int *error_code); +GList* _uaf_parser_parse_asm_response_discover_client(char **asm_response_list, int len, int *error_code); + +_asm_out_t *_uaf_parser_parse_asm_response_reg(const char *asm_response_json, int *error_code); + +_asm_out_t *_uaf_parser_parse_asm_response_auth(const char *asm_response_json, int *error_code); + +_asm_dereg_out_t *_uaf_parser_parse_asm_response_dereg(const char *asm_response_json, int *error_code); + +GList *_uaf_parser_parse_trusted_facets(const char *json); + +_response_t *_uaf_parser_parse_uaf_response(const char *uaf_response); + +_asm_get_reg_out_t *_uaf_parser_parser_asm_get_reg_response(const char *get_reg_resp); + +int _uaf_composer_compose_asm_reg_request(_version_t *version, int auth_index, _fido_asm_reg_in_t *reg_in, char **asm_reg_json); + +int _uaf_composer_compose_asm_auth_request(_version_t *version, int auth_index, _fido_asm_auth_in_t *auth_in, char **asm_auth_json); + +int _uaf_composer_compose_asm_dereg_request(_version_t *version, int auth_index, _matched_auth_dereg_t *dereg_in, char **asm_dereg_json); + +char* _uaf_composer_compose_final_challenge(const char *app_id, const char *challenge, const char *facet_id, const char *ch_bin); + +int _uaf_composer_compose_uaf_process_response_reg(_op_header_t *header, char *final_ch, GList *assertions, char **uaf_response); + +int _uaf_composer_compose_uaf_process_response_auth(_op_header_t *header, char *final_ch, GList *assertions, char **uaf_response); + +char *_uaf_composer_compose_dereg_request(_response_t *uaf_res); + +char *_uaf_composer_compose_get_registrations_request(const char *auth_index); + +int _convert_asm_status_code_to_uaf_error(int asm_status_code); + +_fido_asm_proxy_t* _parse_asm_conf_file(const char *file_name); + + +#endif /* FIDO_JSON_PARSER_H_ */ diff --git a/common/fido_keys.h b/common/fido_keys.h new file mode 100644 index 0000000..9b1e629 --- /dev/null +++ b/common/fido_keys.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef FIDO_KEYS_H +#define FIDO_KEYS_H + +#include + +typedef enum { + _USER_VER_METHOD_MIN = -1, + _USER_VER_METHOD_PRESENCE = 0X01, + _USER_VER_METHOD_FINGERPRINT = 0X02, + _USER_VER_METHOD_PASSCODE = 0X04, + _USER_VER_METHOD_VOICE_PRINT = 0X08, + _USER_VER_METHOD_FACE_PRINT = 0X10, + _USER_VER_METHOD_LOCATION = 0X20, + _USER_VER_METHOD_EYE_PRINT = 0X40, + _USER_VER_METHOD_PATTERN = 0X80, + _USER_VER_METHOD_HAND_PRINT = 0X100, + _USER_VER_METHOD_NONE = 0X200, + _USER_VER_METHOD_ALL = 0X400, + _USER_VER_METHOD_MAX +}_user_verification_method_e; + +#define _UAF_OPERATION_NAME_KEY_REG "Reg" + +#define _UAF_OPERATION_NAME_KEY_AUTH "Auth" + +#define _UAF_OPERATION_NAME_KEY_DE_REG "Dereg" + +#define TAG_UAFV1_REG_ASSERTION 0x3E01 + +#define TAG_UAFV1_AUTH_ASSERTION 0x3E02 + +#define TAG_UAFV1_KRD 0x3E03 + +#define TAG_UAFV1_SIGNED_DATA 0x3E04 + +#define TAG_ATTESTATION_CERT 0x2E05 + +#define TAG_SIGNATURE 0x2E06 + +#define TAG_ATTESTATION_BASIC_FULL 0x3E07 + +#define TAG_ATTESTATION_BASIC_SURROGATE 0x3E08 + +#define TAG_KEYID 0x2E09 + +#define TAG_FINAL_CHALLENGE 0x2E0A + +#define TAG_AAID 0x2E0B + +#define TAG_PUB_KEY 0x2E0C + +#define TAG_COUNTERS 0x2E0D + +#define TAG_ASSERTION_INFO 0x2E0E + +#define TAG_AUTHENTICATOR_NONCE 0x2E0F + +#define TAG_TRANSACTION_CONTENT_HASH 0x2E10 + +#define TAG_EXTENSION 0x3E11, 0x3E12 + +#define TAG_EXTENSION_ID 0x2E13 + +#define TAG_EXTENSION_DATA 0x2E14 + +#endif // FIDO_KEYS_H diff --git a/common/fido_logs.h b/common/fido_logs.h new file mode 100644 index 0000000..1648f30 --- /dev/null +++ b/common/fido_logs.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __FIDO_LOGS_H__ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "org.tizen.fido" + +#ifndef _ERR +#define _ERR(fmt, args...) LOGE("[%s:%d] "fmt"\n", __func__, __LINE__, ##args) +#endif + +#ifndef _DBG +#define _DBG(fmt, args...) LOGD("[%s:%d] "fmt"\n", __func__, __LINE__, ##args) +#endif + +#ifndef _INFO +#define _INFO(fmt, args...) LOGI("[%s:%d] "fmt"\n", __func__, __LINE__, ##args) +#endif + +#endif /* __FIDO_LOGS_H__ */ diff --git a/common/fido_tlv_util.c b/common/fido_tlv_util.c new file mode 100644 index 0000000..c84b2a4 --- /dev/null +++ b/common/fido_tlv_util.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include "fido_internal_types.h" +#include "fido_logs.h" +#include "fido_keys.h" +#include "fido_b64_util.h" +#include "fido_tlv_util.h" + +static _tlv_t* +__get_tlv_pack_by_type(const guchar *tlv_buffer_in, uint16_t type_in, int max_len_in) +{ + //_INFO("__get_tlv_pack_by_type [%u]", type_in); + + int i = 0; + + while (1) { + uint16_t lb = tlv_buffer_in[i + 0]; + uint16_t hb = tlv_buffer_in[i + 1]; + + uint16_t val = hb << 8; + val = val | lb; + + uint16_t type = val; + + lb = 0; + hb = 0; + val = 0; + + lb = tlv_buffer_in[i + 2]; + hb = tlv_buffer_in[i + 3]; + + val = hb << 8; + val = val | lb; + + uint16_t length = val; + + if (type == type_in) { + _tlv_t *tlv = (_tlv_t*)calloc(1, sizeof(_tlv_t)); + tlv->type = type; + tlv->len = length; + if (tlv->len > 0) { + tlv->val = (uint8_t *)calloc(1, tlv->len); + memcpy(tlv->val, tlv_buffer_in + i + 2 + 2, tlv->len); + } + //_INFO("Found key"); + return tlv; + } + + i += 2 + 2 + length; + if (i >= max_len_in) + break; + } + + return NULL; +} + + +_auth_reg_assertion_tlv_t* +_tlv_util_decode_reg_assertion(char *tlv_enc) +{ + _INFO("_tlv_util_decode_reg_assertion"); + + RET_IF_FAIL(tlv_enc != NULL, NULL); + + _INFO("%s", tlv_enc); + + int in_len = strlen(tlv_enc); + int tlv_dec_len = in_len * 1.5; + unsigned char *tlv_dec = calloc(1, tlv_dec_len); + + int r = _fido_b64url_decode((unsigned char *)tlv_enc, in_len, tlv_dec, &tlv_dec_len); + RET_IF_FAIL(r == 0, NULL); + + _INFO("in len = [%d], decoded len = [%d]", in_len, tlv_dec_len); + + _tlv_t *reg_tlv = __get_tlv_pack_by_type(tlv_dec, TAG_UAFV1_REG_ASSERTION, tlv_dec_len); + if (reg_tlv != NULL) { + _INFO("Found TAG_UAFV1_REG_ASSERTION"); + + _free_tlv(reg_tlv); + + int krd_start_idx = 2 + 2; + + _tlv_t *krd_tlv = __get_tlv_pack_by_type(tlv_dec + krd_start_idx, TAG_UAFV1_KRD, (tlv_dec_len - krd_start_idx)); + if (krd_tlv != NULL) { + _INFO("Found TAG_UAFV1_KRD"); + _free_tlv(krd_tlv); + + int krd_inner_start_idx = krd_start_idx + 2 + 2; + + _tlv_t *aaid_tlv = __get_tlv_pack_by_type(tlv_dec + krd_inner_start_idx, TAG_AAID, (tlv_dec_len - krd_inner_start_idx)); + + _tlv_t *key_id_tlv = __get_tlv_pack_by_type(tlv_dec + krd_inner_start_idx, TAG_KEYID, (tlv_dec_len - krd_inner_start_idx)); + + + _auth_reg_assertion_tlv_t *assrt_tlv = (_auth_reg_assertion_tlv_t*)calloc(1, sizeof(_auth_reg_assertion_tlv_t)); + + if (aaid_tlv != NULL) { + _INFO("Found TAG_AAID"); + + assrt_tlv->aaid = (char*)calloc(1, aaid_tlv->len + 1); + memcpy(assrt_tlv->aaid, aaid_tlv->val, aaid_tlv->len); + + _free_tlv(aaid_tlv); + } + + if (key_id_tlv != NULL) { + _INFO("Found TAG_KEYID"); + + assrt_tlv->key_id = (unsigned char*)calloc(1, key_id_tlv->len); + memcpy(assrt_tlv->key_id, key_id_tlv->val, key_id_tlv->len); + + assrt_tlv->key_id_len = key_id_tlv->len; + + _INFO("key_id len = [%d]", key_id_tlv->len); + + _free_tlv(key_id_tlv); + } + + _INFO("Found TAG_KEYID"); + return assrt_tlv; + } + } + + + return NULL; +} + diff --git a/common/fido_tlv_util.h b/common/fido_tlv_util.h new file mode 100644 index 0000000..6d98d1e --- /dev/null +++ b/common/fido_tlv_util.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef FIDO_TLV_UTIL_H_ +#define FIDO_TLV_UTIL_H_ + +#include +#include +#include "fido_internal_types.h" + +_auth_reg_assertion_tlv_t* _tlv_util_decode_reg_assertion(char *tlv_enc); + + +#endif /* FIDO_TLV_UTIL_H_ */ + + diff --git a/common/fido_uaf_types.h b/common/fido_uaf_types.h new file mode 100644 index 0000000..095ec56 --- /dev/null +++ b/common/fido_uaf_types.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef FIDO_UAF_TYPES_H_ +#define FIDO_UAF_TYPES_H_ + +#include +#include + +/** + * @addtogroup CAPI_FIDO_MODULE + * @{ + */ + +/** + * @file fido_uaf_types.h + * @brief The FIDO UAF Client API enums and typedefs. + */ + +/** + * @brief The structure type for the Authenticator handle. + * @since_tizen 3.0 + */ +typedef struct fido_authenticator_s* fido_authenticator_h; + +#define TIZEN_ERROR_FIDO -0x01030000 + +/** + * @brief Enumerations of error codes for FIDO APIs. + * @since_tizen 3.0 + */ +typedef enum +{ + FIDO_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful. */ + FIDO_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory. */ + FIDO_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter. */ + FIDO_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< Empty data. */ + FIDO_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission Denied. */ + + FIDO_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< FIDO is unsupported. */ + FIDO_ERROR_USER_ACTION_IN_PROGRESS = TIZEN_ERROR_FIDO | 0x01, /**< User action is in progress. */ + FIDO_ERROR_USER_CANCELLED = TIZEN_ERROR_FIDO | 0x02, /**< User has canceled the operation. */ + FIDO_ERROR_UNSUPPORTED_VERSION = TIZEN_ERROR_FIDO | 0x03, /**< UAF message's version is not supported. */ + FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR = TIZEN_ERROR_FIDO | 0x04, /**< No suitable authenticators found. */ + FIDO_ERROR_PROTOCOL_ERROR = TIZEN_ERROR_FIDO | 0x05, /**< Protocol error, the interaction may have timed out, or + the UAF message is malformed. */ + FIDO_ERROR_UNTRUSTED_FACET_ID = TIZEN_ERROR_FIDO | 0x06, /**< The caller's id is not allowed to use this operation. */ + FIDO_ERROR_UNKNOWN = TIZEN_ERROR_UNKNOWN /**< Unknown system error.*/ + +} fido_error_e; + +/** + * @brief Authenticator's supported algorithm and encoding. + * @remarks Refer to FIDO UAF Registry document for more details. + * @since_tizen 3.0 + */ +typedef enum +{ + FIDO_AUTH_ALGO_SECP256R1_ECDSA_SHA256_RAW = 0X01, /**< SECP256R1 ECDSA SHA256 Raw */ + FIDO_AUTH_ALGO_SECP256R1_ECDSA_SHA256_DER = 0X02, /**< SECP256R1 ECDSA SHA256 DER*/ + FIDO_AUTH_ALGO_RSASSA_PSS_SHA256_RAW = 0x03, /**< RSA PSS SHA256 Raw*/ + FIDO_AUTH_ALGO_RSASSA_PSS_SHA256_DER = 0x04, /**< RSA PSS SHA256 DER*/ + FIDO_AUTH_ALGO_SECP256K1_ECDSA_SHA256_RAW = 0x05, /**< SECP256K1 ECDSA SHA256 Raw*/ + FIDO_AUTH_ALGO_SECP256K1_ECDSA_SHA256_DER = 0x06 /**< SECP256K1 ECDSA SHA256 DER*/ +} fido_auth_algo_e; + +/** + * @brief Authenticator's supported Attestation type. + * @remarks Refer to FIDO UAF Registry document for more details. + * @since_tizen 3.0 + */ +typedef enum +{ + FIDO_AUTH_ATT_TYPE_BASIC_FULL = 0x3E07, /**< Full basic attestation. */ + FIDO_AUTH_ATT_TYPE_BASIC_SURROGATE = 0x3E08 /**< Surrogate basic attestation. */ +} fido_auth_attestation_type_e; + +/** + * @brief Authenticator's supported user verification method type. + * @remarks Refer to FIDO UAF Registry document for more details. + * @since_tizen 3.0 + */ +typedef enum +{ + FIDO_AUTH_USR_VERIFY_TYPE_PRESENCE = 0x01, /**< User presence verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_FINGERPRINT = 0x02, /**< User fingerprint verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_PASSCODE = 0x04, /**< User passcode verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_VOICEPRINT = 0x08, /**< User voiceprint verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_FACEPRINT = 0x10, /**< User faceprint verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_LOCATION = 0x20, /**< User location verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_EYEPRINT = 0x40, /**< User eyeprint verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_PATTERN = 0x80, /**< User pattern verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_HANDPRINT = 0x100, /**< User handprint verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_NONE = 0x200, /**< Silent verification. */ + FIDO_AUTH_USR_VERIFY_TYPE_ALL = 0x400 /**< If an authenticator sets multiple flags for user verification types, + * it may also set this flag to indicate that all verification methods will be enforced + * (e.g. faceprint AND voiceprint). If flags for multiple user verification methods are set + * and this flag is not set, verification with only one is necessary + * (e.g. fingerprint OR passcode). + */ +} fido_auth_user_verify_type_e; + +/** + * @brief Authenticator's supported key protection method type. + * @remarks Refer to FIDO UAF Registry document for more details. + * @since_tizen 3.0 + */ +typedef enum +{ + FIDO_AUTH_KEY_PROT_TYPE_SOFTWARE = 0x01, /**< Software based key management. */ + FIDO_AUTH_KEY_PROT_TYPE_HARDWARE = 0x02, /**< Hardware based key management. */ + FIDO_AUTH_KEY_PROT_TYPE_TEE = 0x04, /**< Trusted Execution Environment based key management. */ + FIDO_AUTH_KEY_PROT_TYPE_SECURE_ELEMENT = 0x08, /**< Secure Element based key management. */ + FIDO_AUTH_KEY_PROT_TYPE_REMOTE_HANDLE = 0x10 /**< Authenticator does not store (wrapped) UAuth keys at the client, + * but relies on a server-provided key handle. + */ +} fido_auth_key_protection_type_e; + +/** + * @brief Authenticator's supported matcher protection type. + * @remarks Refer to FIDO UAF Registry document for more details. + * @since_tizen 3.0 + */ +typedef enum +{ + FIDO_AUTH_MATCH_PROT_TYPE_SOFTWARE = 0x01, /**< Authenticator's matcher is running in software. */ + FIDO_AUTH_MATCH_PROT_TYPE_TEE = 0x02, /**< Authenticator's matcher is running inside the Trusted Execution Environment. */ + FIDO_AUTH_MATCH_PROT_TYPE_ON_CHIP = 0x04 /**< Aauthenticator's matcher is running on the chip. */ +} fido_auth_matcher_protection_type_e; + +/** + * @brief Authenticator's supproted method to communicate to FIDO user device. + * @remarks Refer to FIDO UAF Registry document for more details. + * @since_tizen 3.0 + */ +typedef enum +{ + FIDO_AUTH_ATTACH_HINT_INTERNAL = 0x01, /**< Authenticator is permanently attached to the FIDO User Device. */ + FIDO_AUTH_ATTACH_HINT_EXTERNAL = 0x02, /**< Authenticator is removable or remote from the FIDO User Device. */ + FIDO_AUTH_ATTACH_HINT_WIRED = 0x04, /**< The external authenticator currently has an exclusive wired connection. */ + FIDO_AUTH_ATTACH_HINT_WIRELESS = 0x08, /**< The external authenticator communicates with the FIDO User Device through + * wireless means. */ + FIDO_AUTH_ATTACH_HINT_NFC = 0x10, /**< Authenticator is able to communicate by NFC to the FIDO User Device. */ + FIDO_AUTH_ATTACH_HINT_BT = 0x20, /**< Authenticator is able to communicate by Bluetooth to the FIDO User Device. */ + FIDO_AUTH_ATTACH_HINT_NW = 0x40, /**< Authenticator is connected to the FIDO User Device ver a non-exclusive network + * (e.g. over a TCP/IP LAN or WAN, as opposed to a PAN or point-to-point connection). + */ + FIDO_AUTH_ATTACH_HINT_READY = 0x80, /**< The external authenticator is in a "ready" state. */ + FIDO_AUTH_ATTACH_HINT_WIFI_DIRECT = 0x100 /**< The external authenticator is able to + * communicate using WiFi Direct with the FIDO User Device. + */ +} fido_auth_attachment_hint_e; + +/** + * @brief Transaction confirmation display capability type. + * @remarks Refer to FIDO UAF Registry document for more details. + * @since_tizen 3.0 + */ +typedef enum +{ + FIDO_AUTH_TC_DISP_TYPE_ANY = 0x01, /**< Some form of transaction confirmation display is available on this authenticator. */ + FIDO_AUTH_TC_DISP_TYPE_PRIVILEGED_SOFTWARE = 0x02, /**< Software-based transaction confirmation display operating in a + * privileged context is available on this authenticator. + */ + FIDO_AUTH_TC_DISP_TYPE_TEE = 0x04, /**< Transaction confirmation display is in a Trusted Execution Environment. */ + FIDO_AUTH_TC_DISP_TYPE_HW = 0x08, /**< Transaction confirmation display based on hardware assisted capabilities is available on this authenticator.*/ + FIDO_AUTH_TC_DISP_TYPE_REMOTE = 0x10 /**< Transaction confirmation display is provided on a distinct device from the FIDO User Device. */ +} fido_auth_tc_display_type_e; + + +/** + * @brief The FIDO Server response for successfull interaction. + * @since_tizen 3.0 + */ +#define FIDO_SERVER_STATUS_CODE_OK 1200 + +/** + * @} + */ + +#endif /* FIDO_UAF_TYPES_H_ */ diff --git a/common/fido_uaf_utils.c b/common/fido_uaf_utils.c new file mode 100644 index 0000000..d440f30 --- /dev/null +++ b/common/fido_uaf_utils.c @@ -0,0 +1,693 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include "fido_logs.h" +#include "fido_internal_types.h" + +void +_free_extension(_extension_t *data) +{ + _INFO(""); + + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->id); + SAFE_DELETE(data->data); + SAFE_DELETE(data); + _INFO(""); +} + +static void +_free_extension_list_item(gpointer data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _free_extension((_extension_t*)data); + _INFO(""); +} + +void +_free_match_criteria(_match_criteria_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + if (data->aaid_list != NULL) + g_list_free_full(data->aaid_list, free); + + if (data->vendor_list != NULL) + g_list_free_full(data->vendor_list, free); + + if (data->key_id_list != NULL) + g_list_free_full(data->key_id_list, free); + + if (data->auth_algo_list != NULL) + g_list_free(data->auth_algo_list); + + if (data->assertion_scheme_list != NULL) + g_list_free_full(data->assertion_scheme_list, free); + + if (data->attestation_type_list != NULL) + g_list_free_full(data->attestation_type_list, free); + + if (data->extension_list != NULL) + g_list_free_full(data->extension_list, _free_extension_list_item); + + SAFE_DELETE(data); + _INFO(""); +} + +static void +_free_uaf_accepted_list_inner_item(gpointer data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _free_match_criteria((_match_criteria_t*)data); + _INFO(""); +} + +static void +_free_uaf_accepted_list_outer_item(gpointer data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + GList *list = (GList*)data; + if (list != NULL) + g_list_free_full(list, _free_uaf_accepted_list_inner_item); + _INFO(""); +} + +static void +_free_uaf_disallowed_list_item(gpointer data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _free_match_criteria((_match_criteria_t*)data); + _INFO(""); +} + +void +_free_policy(_policy_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + if (data->accepted_list != NULL) + g_list_free_full(data->accepted_list, _free_uaf_accepted_list_outer_item); + + if (data->disallowed_list != NULL) + g_list_free_full(data->disallowed_list, _free_uaf_disallowed_list_item); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_op_header(_op_header_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->version); + SAFE_DELETE(data->operation); + SAFE_DELETE(data->app_id); + SAFE_DELETE(data->server_data); + + if (data->ext_list != NULL) + g_list_free_full(data->ext_list, _free_extension_list_item); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_message(_message_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->facet_id); + + _free_op_header(data->header); + + SAFE_DELETE(data->channel_binding); + + switch (data->type) { + + case _MESSAGE_TYPE_REG: + _free_reg_request((_reg_request_t*)(data->data)); + break; + + case _MESSAGE_TYPE_AUTH: + _free_auth_request((_auth_request_t*)(data->data)); + break; + + case _MESSAGE_TYPE_DEREG: + _free_dereg_request((_dereg_request_t*)(data->data)); + break; + + default: + SAFE_DELETE(data->data); + } + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_reg_request(_reg_request_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->challenge); + SAFE_DELETE(data->user_name); + + _free_policy(data->policy); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_display_png_characteristics_descriptor(fido_display_png_characteristics_descriptor_s *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + if (data->plte != NULL) + g_list_free_full(data->plte, free); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_auth_transaction(_auth_transaction_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->content); + SAFE_DELETE(data->content_type); + + _free_display_png_characteristics_descriptor(data->display_charac); + + SAFE_DELETE(data); + _INFO(""); +} + +static void +__free_auth_transaction_list_item(gpointer data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _free_auth_transaction((_auth_transaction_t*)data); + _INFO(""); +} + +void +_free_auth_request(_auth_request_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->challenge); + + _free_policy(data->policy); + + if (data->transaction_list != NULL) + g_list_free_full(data->transaction_list, __free_auth_transaction_list_item); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_dereg_auth_info(_dereg_auth_info_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->aaid); + SAFE_DELETE(data->key_id); + SAFE_DELETE(data); + _INFO(""); +} + +static void +__free_dereg_auth_info_list_item(gpointer data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _free_dereg_auth_info((_dereg_auth_info_t*)data); + _INFO(""); +} + +void +_free_dereg_request(_dereg_request_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + if (data->auth_info_list != NULL) + g_list_free_full(data->auth_info_list, __free_dereg_auth_info_list_item); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_asm_display_png_characteristics_descriptor_t(_fido_asm_display_png_characteristics_descriptor_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + if (data->plte != NULL) + g_list_free_full(data->plte, free); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_fido_asm_proxy(void *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _fido_asm_proxy_t *data_impl = (_fido_asm_proxy_t*)data; + SAFE_DELETE(data_impl->asm_id); + SAFE_DELETE(data_impl->vendor); + SAFE_DELETE(data_impl->bin_path); + SAFE_DELETE(data_impl->dbus_info); + SAFE_DELETE(data_impl->dbus_obj_path); + SAFE_DELETE(data_impl->dbus_interface_name); + SAFE_DELETE(data_impl->dbus_method_name); + + g_object_unref(data_impl->dbus_proxy); + + SAFE_DELETE(data_impl); + + _INFO(""); +} + +void +_free_asm_discover_response(_asm_discover_response_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->asm_id); + SAFE_DELETE(data->asm_response_json); + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_fido_asm_authenticator(fido_authenticator_s *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->asm_id); + + _INFO(""); + + SAFE_DELETE(data->auth_index); + + _INFO(""); + + if (data->key_ids != NULL) + g_list_free_full(data->key_ids, free); + _INFO(""); + + /*TODO : asm_versions is not used anywhere*/ + + SAFE_DELETE(data->aaid); + _INFO(""); + + SAFE_DELETE(data->assertion_scheme); + _INFO(""); + + if (data->attestation_types != NULL) + g_list_free(data->attestation_types); + _INFO(""); + + if (data->supported_extension_IDs != NULL) + g_list_free_full(data->supported_extension_IDs, free); + _INFO(""); + + SAFE_DELETE(data->tc_display_content_type); + _INFO(""); + + if (data->tc_display_png_characteristics != NULL) + g_list_free_full(data->tc_display_png_characteristics, _free_tc_disp_png_char); + _INFO(""); + + SAFE_DELETE(data->title); + _INFO(""); + + SAFE_DELETE(data->description); + _INFO(""); + + SAFE_DELETE(data->icon); + _INFO(""); + + if (data->supported_versions != NULL) + g_list_free_full(data->supported_versions, free); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_fido_asm_authenticator_list_item(gpointer data) +{ + RET_IF_FAIL_VOID(data != NULL); + + fido_authenticator_s *data_impl = (fido_authenticator_s*)data; + + _free_fido_asm_authenticator(data_impl); +} + +void +_free_fido_asm_reg_in(_fido_asm_reg_in_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->app_id); + SAFE_DELETE(data->user_name); + SAFE_DELETE(data->final_challenge); + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_fido_asm_transaction(_fido_asm_transaction_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->content); + SAFE_DELETE(data->content_type); + _free_asm_display_png_characteristics_descriptor_t(data->display_charac); + SAFE_DELETE(data); + _INFO(""); +} + +static void +__free_fido_asm_transaction_list_item(gpointer data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _free_fido_asm_transaction((_fido_asm_transaction_t *)data); + _INFO(""); +} + +void +_free_fido_asm_auth_in(_fido_asm_auth_in_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->app_id); + SAFE_DELETE(data->final_challenge); + if (data->key_ids != NULL) + g_list_free_full(data->key_ids, free); + + if (data->trans_list != NULL) + g_list_free_full(data->trans_list, __free_fido_asm_transaction_list_item); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_fido_asm_dereg_in(_fido_asm_dereg_in_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->app_id); + SAFE_DELETE(data->key_id); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_ui_auth_data(_ui_auth_data_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->asm_id); + SAFE_DELETE(data->auth_index); + SAFE_DELETE(data->label); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_auth_reg_assertion(_auth_reg_assertion_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->assertion_schm); + SAFE_DELETE(data->assertion); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_auth_reg_assertion_list_item(gpointer data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _free_auth_reg_assertion((_auth_reg_assertion_t*)data); + _INFO(""); +} + +void +_free_asm_out(_asm_out_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + switch (data->type) { + + case _ASM_OUT_TYPE_REG: + _free_asm_reg_out((_asm_reg_out_t*)(data->response_data)); + break; + + case _ASM_OUT_TYPE_AUTH: + _free_asm_auth_out((_asm_auth_out_t*)(data->response_data)); + break; + + default: + SAFE_DELETE(data->response_data); + } + + if (data->ext_list != NULL) { + _INFO("Freeing ext list"); + g_list_free_full(data->ext_list, free); + _INFO("After Freeing ext list"); + } + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_asm_reg_out(_asm_reg_out_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->assertion); + SAFE_DELETE(data->assertion_schm); + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_asm_auth_out(_asm_auth_out_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->assertion); + SAFE_DELETE(data->assertion_scheme); + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_tlv(_tlv_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->val); + SAFE_DELETE(data); + + _INFO(""); +} + +void +_free_tc_disp_png_char(gpointer data) +{ + _INFO(""); + if (data == NULL) + return; + + fido_display_png_characteristics_descriptor_s *png = (fido_display_png_characteristics_descriptor_s*)data; + if (png->plte != NULL) + g_list_free_full(png->plte, free); + + SAFE_DELETE(png); + _INFO(""); +} + +void +_free_asm_auth_list(gpointer data) +{ + _INFO("_free_asm_auth_list start"); + + if (data == NULL) + return; + + _free_fido_asm_authenticator((fido_authenticator_s*)data); + + _INFO("_free_asm_auth_list end"); + +} + +void +_free_matched_auth_dereg(_matched_auth_dereg_t *data) +{ + _INFO("_free_matched_auth_dereg start"); + if (data == NULL) + return; + + SAFE_DELETE(data->asm_id); + SAFE_DELETE(data->auth_index); + SAFE_DELETE(data->app_id); + SAFE_DELETE(data->key_id); + + SAFE_DELETE(data); + _INFO("_free_matched_auth_dereg end"); +} + +void +_free_asm_app_reg(_asm_app_reg_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->app_id); + + if (data->key_id_list != NULL) + g_list_free_full(data->key_id_list, free); + + SAFE_DELETE(data); + _INFO(""); +} + +static void +__free_asm_app_reg_list_item(gpointer data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _free_asm_app_reg((_asm_app_reg_t*)data); + _INFO(""); +} + +void +_free_asm_get_reg_out(_asm_get_reg_out_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + if (data->app_reg_list != NULL) + g_list_free_full(data->app_reg_list, __free_asm_app_reg_list_item); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_auth_reg_assertion_tlv(_auth_reg_assertion_tlv_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->aaid); + SAFE_DELETE(data->key_id); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_response(_response_t *data) +{ + _INFO(""); + RET_IF_FAIL_VOID(data != NULL); + + _free_op_header(data->header); + SAFE_DELETE(data->fcp); + + if (data->assertion_list != NULL) + g_list_free_full(data->assertion_list, _free_auth_reg_assertion_list_item); + + SAFE_DELETE(data); + _INFO(""); +} + +void +_free_matched_auth_data(gpointer data) +{ + _INFO("_free_matched_auth_data start"); + if (data == NULL) + return; + + _matched_auth_data_t *match_auth_data = (_matched_auth_data_t*)data; + + SAFE_DELETE(match_auth_data->asm_id); + SAFE_DELETE(match_auth_data->auth_index); + SAFE_DELETE(match_auth_data->label); + SAFE_DELETE(match_auth_data); + + _INFO("_free_matched_auth_data end"); +} diff --git a/doc/fido_doc.h b/doc/fido_doc.h new file mode 100755 index 0000000..b3f433b --- /dev/null +++ b/doc/fido_doc.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __FIDO_DOC_H__ +#define __FIDO_DOC_H__ + +/** + * @defgroup CAPI_FIDO_MODULE FIDO + * @ingroup CAPI_ACCOUNT_FRAMEWORK + * @brief The FIDO APIs provide Fast IDentity Online UAF Client specification APIs. + * + * @section CAPI_FIDO_HEADER Required Header + * \#include + * + * @section CAPI_FIDO_MODULE_OVERVIEW Overview + * The FIDO Universal Authentication Framework (UAF) Client APIs provide APIs for application developers to utilize Device's available authenticators for online service integration. + * The goal of this Universal Authentication Framework is to provide a unified and extensible authentication mechanism that supplants passwords while avoiding the shortcomings of current alternative authentication approaches. + * More details about the FIDO specification can be found in https://fidoalliance.org/specifications/download/ + * + * @defgroup CAPI_FIDO_UAF_MESSAGES_MODULE FIDO UAF MESSAGES + * @ingroup CAPI_FIDO_MODULE + * @brief Fido UAF Messasges + * + * @section CAPI_FIDO_UAF_CLIENT_HEADER Required Header + * \#include + * + * @section CAPI_FIDO_REQUESTS_MODULE_OVERVIEW Overview + * The FIDO UAF Client APIs which process UAF meesages from fido server. + * More details about the FIDO specification can be found in https://fidoalliance.org/specifications/download + * + * @defgroup CAPI_FIDO_AUTHENTICATOR_MODULE FIDO AUTHENTICATOR + * @ingroup CAPI_FIDO_MODULE + * @brief Fido Authenticator + * + * @section CAPI_FIDO_UAF_AUTHENTICATOR_HEADER Required Header + * \#include + * + * @section CAPI_FIDO_AUTHENTICATOR_MODULE_OVERVIEW Overview + * Authenticator information, received in response of fido_foreach_authenticator() call, via fido_authenticator_cb() callback. + * More details about the FIDO specification can be found in https://fidoalliance.org/specifications/download/ +*/ + +#endif /* __FIDO_DOC_H__ */ diff --git a/dummyasm.manifest b/dummyasm.manifest new file mode 100644 index 0000000..75b0fa5 --- /dev/null +++ b/dummyasm.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/fido.manifest b/fido.manifest new file mode 100644 index 0000000..dc03798 --- /dev/null +++ b/fido.manifest @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/fido_svc_ui/CMakeLists.txt b/fido_svc_ui/CMakeLists.txt new file mode 100644 index 0000000..fe4ae45 --- /dev/null +++ b/fido_svc_ui/CMakeLists.txt @@ -0,0 +1,69 @@ +IF(NOT DEFINED UI_PACKAGE_NAME) + SET(UI_PACKAGE_NAME "org.tizen.fidosvcui") +ENDIF(NOT DEFINED UI_PACKAGE_NAME) + +SET(UI_PREFIX "/usr/apps/${UI_PACKAGE_NAME}") + +IF(NOT DEFINED UI_BINDIR) + SET(UI_BINDIR "${UI_PREFIX}/bin") +ENDIF(NOT DEFINED UI_BINDIR) + +IF(NOT DEFINED UI_RESDIR) + SET(UI_RESDIR "${UI_PREFIX}/res") +ENDIF(NOT DEFINED UI_RESDIR) + +IF(NOT DEFINED UI_LOCALEDIR) + SET(UI_LOCALEDIR "${UI_PREFIX}/res/locale") +ENDIF(NOT DEFINED UI_LOCALEDIR) + +IF(NOT DEFINED UI_MANIFESTDIR) + SET(UI_MANIFESTDIR "/usr/share/packages") +ENDIF(NOT DEFINED UI_MANIFESTDIR) + +IF(NOT DEFINED UI_DESKTOP_ICONDIR) + SET(UI_DESKTOP_ICONDIR "/usr/share/icons/default/small") +ENDIF(NOT DEFINED UI_DESKTOP_ICONDIR) + +IF(NOT DEFINED UI_DESKTOP_ICON) + SET(UI_DESKTOP_ICON ${UI_PACKAGE_NAME}.png) +ENDIF(NOT DEFINED UI_DESKTOP_ICON) + +SET(UI_SRCS + ${CMAKE_SOURCE_DIR}/fido_svc_ui/fido_ui_server.c +) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE_NAME}\"") + +INCLUDE(FindPkgConfig) +pkg_check_modules(UI_PKGS REQUIRED + elementary + efl-extension + capi-appfw-application + capi-system-system-settings + dlog + json-glib-1.0 + glib-2.0 + gio-unix-2.0) + +FOREACH(flag ${UI_PKGS_CFLAGS}) + SET(EXTRA_CFLGAS "${EXTRA_CFLGAS} ${flag}") +ENDFOREACH(flag) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_SOURCE_DIR}/common/fido-stub.c ${CMAKE_SOURCE_DIR}/common/fido-stub.h +WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/common/ +COMMAND gdbus-codegen --interface-prefix org.tizen. --generate-c-code fido-stub ${CMAKE_SOURCE_DIR}/common/dbus_interfaces/fido.xml +COMMENT "Generating FIDO GDBus stubs........................") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE ${EXTRA_CFLGAS}") +ADD_EXECUTABLE(${UI_PACKAGE_NAME} ${UI_SRCS} ${CMAKE_SOURCE_DIR}/common/fido-stub.c) +ADD_DEPENDENCIES(${UI_PACKAGE_NAME} ${CMAKE_SOURCE_DIR}/common/fido-stub.h) +ADD_DEPENDENCIES(${UI_PACKAGE_NAME} ${CMAKE_SOURCE_DIR}/common/fido-stub.c) +TARGET_LINK_LIBRARIES(${UI_PACKAGE_NAME} "-pie" ${UI_PKGS_LDFLAGS}) +CONFIGURE_FILE(${UI_PACKAGE_NAME}.xml.in ${UI_PACKAGE_NAME}.xml) + +INSTALL(TARGETS ${UI_PACKAGE_NAME} DESTINATION ${UI_BINDIR}) +INSTALL(FILES ${UI_PACKAGE_NAME}.xml DESTINATION ${UI_MANIFESTDIR}) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/fido_svc_ui/${UI_DESKTOP_ICON} DESTINATION ${UI_DESKTOP_ICONDIR}) diff --git a/fido_svc_ui/fido_ui_server.c b/fido_svc_ui/fido_ui_server.c new file mode 100644 index 0000000..46b6712 --- /dev/null +++ b/fido_svc_ui/fido_ui_server.c @@ -0,0 +1,616 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#if !GLIB_CHECK_VERSION (2, 31, 0) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include "fido_internal_types.h" +#include "fido_logs.h" + +#include "fido-stub.h" +#include "fido_internal_types.h" + +#define _FIDO_SERVICE_UI_DBUS_PATH "/org/tizen/fidosvcui" +#define _FIDO_SERVICE_PATH "/usr/bin/fido-service" + +#define _FREEDESKTOP_SERVICE "org.freedesktop.DBus" +#define _FREEDESKTOP_PATH "/org/freedesktop/DBus" +#define _FREEDESKTOP_INTERFACE "org.freedesktop.DBus" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "fidosvcui" + +static bool auth_option_selected = FALSE; +static Fido *_fido_dbus_obj = NULL; + +typedef struct _ui_data_s { + char *asm_id; + char *auth_index; + char *label; + int att_t; +} ui_data_s; + +typedef struct appdata { + Evas_Object *win; + Evas_Object *conform; + Evas_Object *nf; + Evas_Object *box; + Evas_Object *genlist; + Elm_Genlist_Item_Class* itc; + Evas_Object *group; + Evas_Object *radio; + Evas_Object *btn; + GList *ui_data_list; + GDBusMethodInvocation *invocation; +} appdata_s; + +static appdata_s *ad = NULL; + +static void +__free_ui_data(ui_data_s *data) +{ + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->asm_id); + SAFE_DELETE(data->auth_index); + SAFE_DELETE(data->label); + + SAFE_DELETE(data); +} + +static void +__add_string_to_json_object(JsonBuilder *json_obj, const char *key, const char *val) +{ + if (key == NULL || val == NULL) + return; + + json_builder_set_member_name(json_obj, key); + json_builder_add_string_value(json_obj, val); +} + +static void +__add_int_to_json_object(JsonBuilder *json_obj, const char *key, int val) +{ + if (key == NULL || val == _INVALID_INT) + return; + + json_builder_set_member_name(json_obj, key); + json_builder_add_int_value(json_obj, val); +} + +static void +__init_dbus(void) +{ + _INFO("init_dbus"); +#if !GLIB_CHECK_VERSION(2,35,0) + g_type_init(); +#endif + + GDBusConnection *connection = NULL; + GError *error = NULL; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + + _INFO("after g_bus_get_sync"); + + + /* Create the object */ + _fido_dbus_obj = fido_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, + _FIDO_DBUS_NAME, + _FIDO_DBUS_PATH, + NULL, + &error); +} + +static Fido * +__dbus_proxy_get_instance(int time_out) +{ + _INFO("_dbus_proxy_get_instance singleton"); + + static pthread_once_t onceBlock = PTHREAD_ONCE_INIT; + if (_fido_dbus_obj == NULL) { + pthread_once(&onceBlock, __init_dbus); + if (_fido_dbus_obj == NULL) { + _ERR("init_dbus failed"); + onceBlock = PTHREAD_ONCE_INIT; + } + } + _INFO("_dbus_proxy_get_instance end"); + + g_dbus_proxy_set_default_timeout(G_DBUS_PROXY(_fido_dbus_obj), time_out); + + return _fido_dbus_obj; +} + +static void +__send_response_to_fido_svc(int error, const char *ui_resp) +{ + auth_option_selected = FALSE; + + Fido *dbus_proxy = __dbus_proxy_get_instance(_DBUS_TIMEOUT_USE_DEFAULT); + if (dbus_proxy == NULL) { + _ERR("DBus proxy failed"); + return; + } + + _INFO("Sending to FIDO Service"); + + GError *dbus_err = NULL; + if (ui_resp == NULL) + fido_call_ui_response_sync(dbus_proxy, FIDO_ERROR_USER_CANCELLED, _EMPTY_JSON_STRING, NULL, &dbus_err); + else + fido_call_ui_response_sync(dbus_proxy, error, ui_resp, NULL, &dbus_err); + + if (dbus_err != NULL) + g_error_free(dbus_err); + + _INFO("UI end"); +} + +char* +_create_json_response(ui_data_s *selected_auth) +{ + _INFO("_create_json_response"); + + /*Builder start*/ + JsonBuilder *builder = json_builder_new(); + json_builder_begin_object(builder); + + /*requestType*/ + __add_string_to_json_object(builder, UI_DATA_ASM_ID, selected_auth->asm_id); + __add_string_to_json_object(builder, UI_DATA_AUTH_INDEX, selected_auth->auth_index); + __add_string_to_json_object(builder, UI_DATA_LABEL, selected_auth->label); + __add_int_to_json_object(builder, UI_DATA_ATT_TYPE, selected_auth->att_t); + + json_builder_end_object(builder); + /*Builder end*/ + + JsonGenerator *gen = json_generator_new(); + JsonNode *root_builder = json_builder_get_root(builder); + json_generator_set_root(gen, root_builder); + + json_node_free(root_builder); + g_object_unref(builder); + + gsize len = 0; + char *json = json_generator_to_data(gen, &len); + if (json != NULL) { + + if (gen != NULL) + g_object_unref(gen); + + _INFO("%s", json); + _INFO("_create_json_response end"); + + return json; + } + + g_object_unref(gen); + + _INFO("_create_json_response fail"); + return NULL; +} + +void +_list_destroy(gpointer data) +{ + ui_data_s *list_data = (ui_data_s *) data; + SAFE_DELETE(list_data->auth_index); + SAFE_DELETE(list_data->label); +} + +void +_hide_ui(void) +{ + elm_genlist_clear(ad->genlist); + g_list_free_full(ad->ui_data_list, (GDestroyNotify) _list_destroy); + ad->ui_data_list = NULL; + evas_object_hide(ad->win); +} + +void genlist_select_cb(void *data, Evas_Object *obj, void *event_info) +{ + _INFO("genlist_select_cb"); + + if (data == NULL) { + _INFO("data is NULL"); + return; + } + + if (event_info == NULL) { + _INFO("event_info is NULL"); + return; + } + + ui_data_s *selected_auth = (ui_data_s*) data; + auth_option_selected = TRUE; + + Elm_Object_Item *item = (Elm_Object_Item *) event_info; + char *sel_txt = (char *) elm_object_item_data_get(item); + + if (!strcmp(sel_txt, selected_auth->label)) { + char *response = _create_json_response(selected_auth); + if (response != NULL) { + _hide_ui(); + + _INFO("sending response to ui adaptor"); + __send_response_to_fido_svc(FIDO_ERROR_NONE, response); + + SAFE_DELETE(response); + } + } +} + +static char* +_item_label_get(void *data, Evas_Object *obj, const char *part) +{ + char buf[256]; + snprintf(buf, sizeof(buf), "%s", (char*) data); + return strdup(buf); +} + +void +_auth_arr_cb(JsonArray *array, guint index, JsonNode *element_node, gpointer user_data) +{ + _INFO("_auth_arr_cb"); + + JsonObject *obj = NULL; + obj = json_node_get_object(element_node); + if (!obj) { + _ERR("json_node_get_object() failed"); + return; + } + + ui_data_s *ui_data = (ui_data_s *) calloc(1, sizeof(ui_data_s)); + if (!ui_data) { + _ERR("Out of memory"); + return; + } + + const char *asm_id = json_object_get_string_member(obj, UI_DATA_ASM_ID); + if (!asm_id) { + _ERR("json_object_get_string_member() failed"); + + __free_ui_data(ui_data); + return; + } + + const char *auth_idx = NULL; + auth_idx = json_object_get_string_member(obj, UI_DATA_AUTH_INDEX); + if (!auth_idx) { + _ERR("json_object_get_string_member() failed"); + + __free_ui_data(ui_data); + return; + } + + const char *label = NULL; + label = json_object_get_string_member(obj, UI_DATA_LABEL); + + int att = -1; + att = json_object_get_int_member(obj, UI_DATA_ATT_TYPE); + + ui_data->asm_id = strdup(asm_id); + + ui_data->auth_index = strdup(auth_idx); + if (label == NULL) { + ui_data->label = calloc(1, 128); + snprintf(ui_data->label, 127, "%s", "Unknown Authenticator"); + } + else + ui_data->label = strdup(label); + + ui_data->att_t = att; + ad->ui_data_list = g_list_append(ad->ui_data_list, ui_data); + + _INFO("Adding to ui_data list | auth_index %s | label %s | att_type %d", + auth_idx, ui_data->label, att); + + elm_genlist_item_append(ad->genlist, ad->itc, ui_data->label, NULL, + ELM_GENLIST_ITEM_NONE, genlist_select_cb, ui_data); + +} + +static void +_parse_json_ui_in(const char *ui_auth_json) +{ + _INFO("_parse_json_ui_in data %s", ui_auth_json); + + char * ui_auth = strdup(ui_auth_json); + GError *parse_err = NULL; + JsonParser *parser = NULL; + JsonNode *root = NULL; + JsonArray *auth_data_arr = NULL; + + parser = json_parser_new(); + if (!parser) { + _ERR("json_parser_new failed"); + goto CATCH; + } + + json_parser_load_from_data(parser, ui_auth, -1, &parse_err); + if (parse_err != NULL) { + _ERR("json parse failure"); + goto CATCH; + } + + root = json_parser_get_root(parser); + if (!root) { + _ERR("json_parser_get_root() failed"); + goto CATCH; + } + + auth_data_arr = json_node_get_array(root); + if (!auth_data_arr) { + _ERR("json_node_get_array() failed"); + goto CATCH; + } + + /* Genlist Item */ + ad->itc = elm_genlist_item_class_new(); + ad->itc->item_style = "default"; + ad->itc->func.text_get = _item_label_get; + ad->itc->func.content_get = NULL; + ad->itc->func.state_get = NULL; + + json_array_foreach_element(auth_data_arr, _auth_arr_cb, NULL); + +CATCH: + if (parser != NULL) { + g_object_unref(parser); + parser = NULL; + } + + if (parse_err != NULL) { + g_error_free(parse_err); + parse_err = NULL; + } + + SAFE_DELETE(ui_auth); + + return; +} + +// TODO button callback +/* +static void btn_clicked_cb(void *data, Evas_Object *obj, void *event_info) { + + _INFO("clicked event on Button"); + + if (auth_option_selected == TRUE && selected_auth != NULL) { + + char *selected_auth_json = _create_json_response(selected_auth); + + _INFO("sending selected authenticator response"); + fidosvcui_complete_ui_auth_request(ad->object, ad->invocation, 0, selected_auth_json); + + } +} +*/ + +static void +_win_back_cb(void *data, Evas_Object *obj, void *event_info) +{ + if (auth_option_selected == FALSE) { + _ERR("Authenticator not selected by user"); + _hide_ui(); + __send_response_to_fido_svc(FIDO_ERROR_USER_CANCELLED, NULL); + } +} + +static void +_create_ui(void) +{ + _INFO("_create_ui"); + + /* Window */ + //ad->win = elm_win_add(NULL, UI_SVC_PACKAGE, ELM_WIN_BASIC); + ad->win = elm_win_util_standard_add(_UI_SVC_PACKAGE, "Authenticator Selection UI"); + if (ad->win != NULL) + _INFO("elm_win_util_standard_add successful"); + else + _ERR("elm_win_util_standard_add failed"); + + elm_win_autodel_set(ad->win, EINA_TRUE); + + if (elm_win_wm_rotation_supported_get(ad->win)) { + int rots[4] = { 0, 90, 180, 270 }; + elm_win_wm_rotation_available_rotations_set(ad->win, + (const int *) (&rots), 4); + } + + eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, _win_back_cb, ad); + evas_object_smart_callback_add(ad->win, "unfocused", _win_back_cb, NULL); + + /* Conformant */ + ad->conform = elm_conformant_add(ad->win); + elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW); + elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE); + evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_win_resize_object_add(ad->win, ad->conform); + evas_object_show(ad->conform); + + /* Naviframe */ + ad->nf = elm_naviframe_add(ad->conform); + elm_object_content_set(ad->conform, ad->nf); + evas_object_show(ad->nf); + + /* Box */ + ad->box = elm_box_add(ad->nf); + + /* Genlist */ + ad->genlist = elm_genlist_add(ad->box); + elm_genlist_homogeneous_set(ad->genlist, EINA_TRUE); + + /* Radio */ + Evas_Object *radio_main = elm_radio_add(ad->genlist); + elm_radio_state_value_set(radio_main, 0); + elm_radio_value_set(radio_main, 0); + evas_object_data_set(ad->genlist, "radio_main", radio_main); + + evas_object_size_hint_weight_set(ad->genlist, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(ad->genlist, EVAS_HINT_FILL, + EVAS_HINT_FILL); + evas_object_show(ad->genlist); + elm_box_pack_end(ad->box, ad->genlist); + + //~ /* Button */ // TODO check button visibility + //~ ad->btn = elm_button_add(ad->box); + //~ elm_object_text_set(ad->btn, "OK"); + //~ evas_object_size_hint_weight_set(ad->btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + //~ evas_object_size_hint_align_set(ad->btn, EVAS_HINT_FILL, EVAS_HINT_FILL); + + //~ Evas_Object *btn_bg = elm_bg_add(ad->btn); + //~ elm_bg_color_set(btn_bg, 90, 160, 200); + + //~ evas_object_smart_callback_add(ad->btn, "clicked", btn_clicked_cb, ad); + //~ evas_object_show(ad->btn); + //~ elm_box_pack_end(ad->box, ad->btn); + + + elm_naviframe_item_push(ad->nf, "Select Authenticator", + NULL, NULL, ad->box, NULL); + + /* Keep window hidden after base gui is set up */ + //evas_object_hide(ad->win); + +} + +static bool +app_create(void *data) +{ + ad = data; + _create_ui(); + + return true; + } + +static void +app_control(app_control_h app_control, void *data) +{ + //_UI_IPC_KEY_REQ + RET_IF_FAIL_VOID(app_control != NULL); + + char *req_json = NULL; + app_control_get_extra_data(app_control, _UI_IPC_KEY_REQ, &req_json); + RET_IF_FAIL_VOID(req_json != NULL); + + _parse_json_ui_in(req_json); + + evas_object_show(ad->win); +} + +static void +app_pause(void *data) +{ + + } + +static void +app_resume(void *data) +{ + + } + +static void +app_terminate(void *data) +{ + +} + +static void +ui_app_lang_changed(app_event_info_h event_info, void *user_data) +{ + + char *locale = NULL; + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale); + elm_language_set(locale); + free(locale); + return; + } + +static void +ui_app_orient_changed(app_event_info_h event_info, void *user_data) +{ + return; + } + +static void +ui_app_region_changed(app_event_info_h event_info, void *user_data) +{ +} + +static void +ui_app_low_battery(app_event_info_h event_info, void *user_data) +{ + + } + +static void +ui_app_low_memory(app_event_info_h event_info, void *user_data) +{ + +} + +EXPORT_API int +main(int argc, char *argv[]) +{ + appdata_s ad = {0,}; + int ret = 0; + + ui_app_lifecycle_callback_s event_callback = {0,}; + app_event_handler_h handlers[5] = {NULL, }; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.pause = app_pause; + event_callback.resume = app_resume; + event_callback.app_control = app_control; + + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad); + ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]); + + ret = ui_app_main(argc, argv, &event_callback, &ad); + if (ret != APP_ERROR_NONE) { + _INFO("app_main() is failed. err = %d", ret); + } + + return ret; +} diff --git a/fido_svc_ui/org.tizen.fidosvcui.png b/fido_svc_ui/org.tizen.fidosvcui.png new file mode 100644 index 0000000..9765b1b Binary files /dev/null and b/fido_svc_ui/org.tizen.fidosvcui.png differ diff --git a/fido_svc_ui/org.tizen.fidosvcui.xml.in b/fido_svc_ui/org.tizen.fidosvcui.xml.in new file mode 100644 index 0000000..28b7407 --- /dev/null +++ b/fido_svc_ui/org.tizen.fidosvcui.xml.in @@ -0,0 +1,12 @@ + + + + + + org.tizen.fidosvcui.png + + + http://tizen.org/privilege/account.read + http://tizen.org/privilege/account.write + + diff --git a/include/fido.h b/include/fido.h new file mode 100644 index 0000000..30e0c45 --- /dev/null +++ b/include/fido.h @@ -0,0 +1,45 @@ + +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _FIDO_H_ +#define _FIDO_H_ + +#include + +#include +#include +#include + +/** + * Tizen FIDO UAF Client Framework. + * Refer to https://fidoalliance.org/specifications/download/ about FIDO UAF. + * Also FIDO server document needs to be referred for using end points and additional parameters. + */ + +/** + * @addtogroup CAPI_FIDO_MODULE + * @{ + */ + +/* End of FIDO APIs */ +/** + * @} + */ + +#endif // _FIDO_H_ + diff --git a/include/fido_uaf_authenticator.h b/include/fido_uaf_authenticator.h new file mode 100755 index 0000000..d538384 --- /dev/null +++ b/include/fido_uaf_authenticator.h @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _FIDO_UAF_AUTH_H_ +#define _FIDO_UAF_AUTH_H_ + +#include "fido_uaf_types.h" + +/** + * @file fido_uaf_authenticator.h + * @brief Authenticator information, received in response of fido_foreach_authenticator() call, + * via fido_authenticator_cb() callback. + */ + +/** + * @addtogroup CAPI_FIDO_AUTHENTICATOR_MODULE + * @{ + */ + +/** + * @brief Called once for each result of calling fido_foreach_authenticator() + * @since_tizen 3.0 + * + * @param[out] auth_info The Authenticator info handle. This param will be freed by framework. + * @param[out] user_data The user data that was attached during fido_foreach_authenticator() call. + * @see fido_foreach_authenticator() + */ +typedef void (*fido_authenticator_cb)(const fido_authenticator_h auth_info, void *user_data); + +/** + * @brief Retrieves all the available FIDO authenticators supported by this Device. + * @details fido_authenticator_cb() callback is called synchronously once for each authenticator. + * @since_tizen 3.0 + * + * + * @param[in] cb The iteration callback handle. + * @param[in] user_data The user data handle. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #FIDO_ERROR_PERMISSION_DENIED The application does not have permission to call this API. + * @retval #FIDO_ERROR_NOT_SUPPORTED FIDO is not supported on this device. + */ +EXPORT_API int fido_foreach_authenticator(fido_authenticator_cb cb, void *user_data); + +/** + * @brief Gets the Authenticator title. + * @since_tizen 3.0 + * + * @remarks The application must free title using free(). + * @param[in] auth The Authenticator handle. + * @param[out] title The title. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_title(const fido_authenticator_h auth, char **title); + +/** + * @brief Retrieves the Authenticator AAID(Authenticator Attestation ID). + * @since_tizen 3.0 + * + * @remarks The application must free aaid using free(). + * @param[in] auth The Authenticator handle. + * @param[out] aaid The AAID. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_aaid(const fido_authenticator_h auth, char **aaid); + +/** + * @brief Retrieves the Authenticator description + * @since_tizen 3.0 + * + * @remarks The application must free desc using free(). + * @param[in] auth The Authenticator handle. + * @param[out] desc The description. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_description(const fido_authenticator_h auth, char **desc); + +/** + * @brief Retrieves the Authenticator assertion scheme. + * @since_tizen 3.0 + * + * @remarks The application must free scheme using free().Refer to FIDO UAF Registry document for more details. + * @param[in] auth The Authenticator handle. + * @param[out] scheme The assertion scheme. UAFV1TLV is the default assertion scheme. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_assertion_scheme(const fido_authenticator_h auth, char **scheme); + +/** + * @brief Retrieves the Authenticator algorithm + * @since_tizen 3.0 + * + * @param[in] auth The Authenticator handle. + * @param[out] algo The authenitcation algorithm. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_algorithm(const fido_authenticator_h auth, fido_auth_algo_e *algo); + +/** + * @brief Called once for each result of calling fido_authenticator_foreach_attestation_type() + * @since_tizen 3.0 + * + * @param[out] att_type The Authenticator attestation type. + * @param[out] user_data The user data that was attached during fido_authenticator_foreach_attestation_type() call. + */ +typedef void (*fido_attestation_type_cb)(fido_auth_attestation_type_e att_type, void *user_data); + +/** + * @brief Retrieves all the available attestation types for this Authenticator. + * @since_tizen 3.0 + * + * @param[in] auth The Authenticator handle. + * @param[in] cb The iteration callback. + * @param[in] user_data The user data. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_foreach_attestation_type(const fido_authenticator_h auth, fido_attestation_type_cb cb, + void *user_data); + +/** + * @brief Retrieves the user verification method of this Authenticator. + * @since_tizen 3.0 + * + * @param[in] auth The Authenticator handle. + * @param[out] user_verification The user verification method. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_verification_method(const fido_authenticator_h auth, + fido_auth_user_verify_type_e *user_verification); + +/** + * @brief Retrieves the key protection method of this Authenticator. + * @since_tizen 3.0 + * + * @param[in] auth The Authenticator handle. + * @param[out] key_protection The key protection method. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_key_protection_method(const fido_authenticator_h auth, + fido_auth_key_protection_type_e *key_protection); + +/** + * @brief Retrieves the matcher protection method of this Authenticator. + * @since_tizen 3.0 + * + * @param[in] auth The Authenticator handle. + * @param[out] matcher_protection The matcher protection method. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_matcher_protection_method(const fido_authenticator_h auth, + fido_auth_matcher_protection_type_e *matcher_protection); + +/** + * @brief Retrieves the attachment hint of this Authenticator. + * @since_tizen 3.0 + * + * @param[in] auth The Authenticator handle. + * @param[out] attachment_hint The matcher protection method. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_attachment_hint(const fido_authenticator_h auth, + fido_auth_attachment_hint_e *attachment_hint); + +/** + * @brief Checks if the Authenticator is Second factor only which is supported by U2F standards. + * @since_tizen 3.0 + * + * @param[in] auth The Authenticator handle. + * + * @return @c true if its only second factor, + * otherwise false. + */ +EXPORT_API bool fido_authenticator_get_is_second_factor_only(const fido_authenticator_h auth); + +/** + * @brief Retrieves the Transaction Confirmation display type of this Authenticator. + * @since_tizen 3.0 + * + * @param[in] auth The Authenticator handle. + * @param[out] tc_display The TC display type. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_tc_discplay(const fido_authenticator_h auth, + fido_auth_tc_display_type_e *tc_display); + +/** + * @brief Retrieves the Transaction Confirmation display content type of this Authenticator. + * @since_tizen 3.0 + * + * @remarks The application must free tc_display_content_type using free(). + * @param[in] auth The Authenticator handle. + * @param[out] tc_display_content_type The TC display content type which is supported MIME type [RFC2049] such as text/plain or image/png. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_tc_display_type(const fido_authenticator_h auth, char **tc_display_content_type); + +/** + * @brief Retrieves the icon of this Authenticator. + * @since_tizen 3.0 + * + * @remarks The application must free icon using free(). + * @param[in] auth The Authenticator handle. + * @param[out] icon The icon. Portable Network Graphic (PNG) format image file representing the icon encoded as a data: url[RFC2397]. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_authenticator_get_icon(const fido_authenticator_h auth, char **icon); + +/** + * @} + */ + +#endif diff --git a/include/fido_uaf_client.h b/include/fido_uaf_client.h new file mode 100755 index 0000000..c809a32 --- /dev/null +++ b/include/fido_uaf_client.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef FIDO_UAF_CLIENT_H_ +#define FIDO_UAF_CLIENT_H_ + +#include + +/** + * @file fido_uaf_client.h + * @brief The FIDO UAF Client APIs. + */ + +/** + * @addtogroup CAPI_FIDO_MODULE + * @{ + */ + +/** + * @brief Gets the FIDO client vendor name. + * @since_tizen 3.0 + * + * @remarks The application must free vendor_name using free(). + * @param[out] vendor_name The vendor name. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_get_client_vendor(char **vendor_name); + +/** + * @brief Gets the FIDO client vendor version information. + * @since_tizen 3.0 + * + * @param[out] client_major_version The FIDO client major version. + * @param[out] client_minor_version The FIDO client minor version. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + */ +EXPORT_API int fido_get_client_version(int *client_major_version, int *client_minor_version); + +/** + * @} + */ + +/** + * @addtogroup CAPI_FIDO_UAF_MESSAGES_MODULE + * @{ + */ + +/** + * @brief Checks whether the FIDO message can be processed. + * @since_tizen 3.0 + * + * @param[in] uaf_message_json The FIDO message in json format which is recieved from the relying party server. + * @param[out] is_supported True if the message can be handled by the device, else false. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #FIDO_ERROR_NOT_SUPPORTED FIDO is not supported + * @retval #FIDO_ERROR_PERMISSION_DENIED The application does not have permission to call this API. + * @retval #FIDO_ERROR_UNSUPPORTED_VERSION The UAFMessage does not specify a protocol version supported by this FIDO UAF Client. + * @retval #FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR No suitable authenticators found. + * @retval #FIDO_ERROR_PROTOCOL_ERROR The interaction may have timed out, or the UAF message is malformed. + * @retval #FIDO_ERROR_UNTRUSTED_FACET_ID The caller's id is not allowed to use this operation. + * + */ +EXPORT_API int fido_uaf_is_supported(const char *uaf_message_json, bool *is_supported); + +/** + * @brief Called when fido_uaf_get_response_message() response comes. + * @since_tizen 3.0 + * + * @param[in] tizen_error_code Tizen platform error code. + * @param[in] uaf_response_json FIDO resonse message in json format. + * @param[in] user_data The user data passed from the callback function. + * + * @pre fido_uaf_get_response_message() must be called to get this callback invoked. + * @see fido_uaf_get_response_message() + */ +typedef void (*fido_uaf_response_message_cb) (fido_error_e tizen_error_code, const char *uaf_response_json, void *user_data); + +/** + * @brief Processes the given FIDO UAF message. + * @details The response is delivered via fido_uaf_response_message_cb(). Depending on the FIDO message type, this may involve user interactions. + * + * @since_tizen 3.0 + * + * @param[in] uaf_request_json The FIDO UAF message in json format which is recieved from the relying party server. + * @param[in] channel_binding The channel binding data in json format which is recieved from the relying party server. + * @param[in] callback The callback to receive response. + * @param[in] user_data The user data to be passed to the callback function. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #FIDO_ERROR_NOT_SUPPORTED FIDO is not supported + * @retval #FIDO_ERROR_USER_ACTION_IN_PROGRESS User action is in progress. + * @retval #FIDO_ERROR_USER_CANCELLED User has canceled the operation. + * @retval #FIDO_ERROR_PERMISSION_DENIED The application does not have permission to call this API. + * @retval #FIDO_ERROR_UNSUPPORTED_VERSION The UAFMessage does not specify a protocol version supported by this FIDO UAF Client. + * @retval #FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR No suitable authenticators found. + * @retval #FIDO_ERROR_PROTOCOL_ERROR The interaction may have timed out, or the UAF message is malformed. + * @retval #FIDO_ERROR_UNTRUSTED_FACET_ID The caller's id is not allowed to use this operation. + * + * @see fido_uaf_response_message_cb() + */ +EXPORT_API int fido_uaf_get_response_message(const char *uaf_request_json, const char *channel_binding, + fido_uaf_response_message_cb callback, void *user_data); + +/** + * @brief Notifies the server result to the FIDO client. FIDO Server sends the result of processing a UAF message to FIDO client. + * @remarks This is especially important as a new registration may be considered by the client to be in a pending state + * until it is communicated that the server accepted it. + * + * @since_tizen 3.0 + * + * @param[in] response_code The status code received from Server, FIDO_SERVER_STATUS_CODE_OK implies success. + * @param[in] uaf_response_json The FIDO response message sent to server in json format. + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #FIDO_ERROR_NONE Successful + * @retval #FIDO_ERROR_OUT_OF_MEMORY Out of Memory + * @retval #FIDO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #FIDO_ERROR_NOT_SUPPORTED FIDO is not supported + * @retval #FIDO_ERROR_PERMISSION_DENIED The application does not have permission to call this API. + * @retval #FIDO_ERROR_UNSUPPORTED_VERSION The UAFMessage does not specify a protocol version supported by this FIDO UAF Client. + * @retval #FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR No suitable authenticators found. + * @retval #FIDO_ERROR_PROTOCOL_ERROR The interaction may have timed out, or the UAF message is malformed. + * @retval #FIDO_ERROR_UNTRUSTED_FACET_ID The caller's id is not allowed to use this operation. + * + * @see fido_uaf_response_message_cb() + */ +EXPORT_API int fido_uaf_set_server_result(int response_code, const char *uaf_response_json); + +/** + * @} + */ + +#endif /* FIDO_UAF_CLIENT_H_ */ diff --git a/org.tizen.FidoSample.manifest b/org.tizen.FidoSample.manifest new file mode 100755 index 0000000..058c45f --- /dev/null +++ b/org.tizen.FidoSample.manifest @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.tizen.fidosvcui.manifest b/org.tizen.fidosvcui.manifest new file mode 100755 index 0000000..75b0fa5 --- /dev/null +++ b/org.tizen.fidosvcui.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/fido-client.spec b/packaging/fido-client.spec new file mode 100644 index 0000000..4d8d775 --- /dev/null +++ b/packaging/fido-client.spec @@ -0,0 +1,218 @@ + +Name: fido-client +Summary: Tizen FIDO Client +Version: 0.0.1 +Release: 1 +Group: Social & Content/API +License: Apache-2.0 +Source0: fido-client-%{version}.tar.gz +Source1: org.tizen.fido.service +Source2: org.tizen.fido.conf +Source3: org.tizen.fido.service + +Source4: org.tizen.dummyasm.service +Source5: org.tizen.dummyasm.conf + +BuildRequires: cmake +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(glib-2.0) >= 2.26 +BuildRequires: pkgconfig(gio-unix-2.0) +BuildRequires: pkgconfig(cynara-client) +BuildRequires: pkgconfig(cynara-session) +BuildRequires: pkgconfig(cynara-creds-gdbus) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(json-glib-1.0) +##BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-appfw-app-manager) +BuildRequires: pkgconfig(libsoup-2.4) +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(efl-extension) +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(bundle) +BuildRequires: python-xml + +Requires(post): /sbin/ldconfig +Requires(post): /usr/bin/sqlite3 +Requires(postun): /sbin/ldconfig + +%description +Tizen FIDO Client + +%package devel +Summary: Development files for %{name} +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +%description devel +Development files for %{name} + +%prep +%setup -q + +%build +#export CFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wswitch-default" +#export CXXFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wswitch-default -Wnon-virtual-dtor -Wno-c++0x-compat" +#export CFLAGS+=" -Wno-unused-parameter -Wno-empty-body" +#export CXXFLAGS+=" -Wno-unused-parameter -Wno-empty-body" + +#export CFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow -fno-common" +#export CXXFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow" + +export CFLAGS="${CFLAGS} -fPIC -fvisibility=hidden" +cmake . -DCMAKE_INSTALL_PREFIX=/usr + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +cp %{_builddir}/%{name}-%{version}/LICENSE.Apache-2.0 %{buildroot}/usr/share/license/%{name} +%make_install + +mkdir -p %{buildroot}/usr/share/dbus-1/system-services +install -m 0644 %SOURCE1 %{buildroot}/usr/share/dbus-1/system-services/org.tizen.fido.service + +mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d +install -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/dbus-1/system.d/ + +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants +install -m 644 %SOURCE3 %{buildroot}%{_unitdir}/org.tizen.fido.service +%install_service multi-user.target.wants org.tizen.fido.service + + +mkdir -p %{buildroot}/usr/share/dbus-1/system-services +install -m 0644 %SOURCE4 %{buildroot}/usr/share/dbus-1/system-services/org.tizen.dummyasm.service + +mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d +install -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/dbus-1/system.d/ + +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants +install -m 644 %SOURCE4 %{buildroot}%{_unitdir}/org.tizen.dummyasm.service +%install_service multi-user.target.wants org.tizen.dummyasm.service + +install -m 0644 test/Dummy_ASM_DBUS/dummy_asm.json %{buildroot}%{_libdir}/fido/asm/dummy_asm.json + +##rm -rf %{buildroot}/usr/lib/fido + +%post +mkdir -p /usr/lib/fido/asm/ +chsmack -a '_' /usr/lib/fido/ +chsmack -a '_' /usr/lib/fido/asm/ +/sbin/ldconfig + +%postun +/sbin/ldconfig + +%files +/usr/share/license/%{name} +%{_libdir}/*.so.* +%manifest fido.manifest +%config %{_sysconfdir}/dbus-1/system.d/org.tizen.fido.conf +%{_bindir}/fido-service +%attr(0644,root,root) %{_unitdir}/org.tizen.fido.service +%attr(0644,root,root) %{_unitdir}/multi-user.target.wants/org.tizen.fido.service +%attr(0644,root,root) /usr/share/dbus-1/system-services/org.tizen.fido.service + +%files devel +%defattr(-,root,root,-) +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc +%{_includedir}/*.h +/opt/usr/devel/fido/tc/* + + +################################################################################# +# FIDO Service UI + +%package -n org.tizen.fidosvcui +Summary: FIDO Service UI +Group: Account +#Requires: %{name} = %{version}-%{release} + +BuildRequires: cmake +BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-system-system-settings) +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(efl-extension) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(bundle) +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(glib-2.0) >= 2.26 +BuildRequires: pkgconfig(gio-unix-2.0) +Requires: fido-client + +%description -n org.tizen.fidosvcui +FIDO Service UI + +%files -n org.tizen.fidosvcui +%defattr(-,root,root,-) +/usr/share/license/%{name} +%manifest org.tizen.fidosvcui.manifest +/usr/apps/org.tizen.fidosvcui/bin/* +##/usr/apps/org.tizen.fidosvcui/res/* +/usr/share/packages/org.tizen.fidosvcui.xml +/usr/share/icons/default/small/org.tizen.fidosvcui.png + +################################################################################# +# FIDO Dummy ASM +%package -n dummyasm +Summary: FIDO Dummy ASM (Internal Dev) +Group: Account/Testing + +BuildRequires: cmake +BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-system-system-settings) +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(efl-extension) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(glib-2.0) >= 2.26 +BuildRequires: pkgconfig(gio-unix-2.0) +BuildRequires: pkgconfig(libtzplatform-config) +Requires: fido-client + +%description -n dummyasm +This is a dummy ASM. + +%files -n dummyasm +%manifest dummyasm.manifest +%config %{_sysconfdir}/dbus-1/system.d/org.tizen.dummyasm.conf +%{_bindir}/dummyasm-service +%attr(0644,root,root) %{_unitdir}/org.tizen.dummyasm.service +%attr(0644,root,root) %{_unitdir}/multi-user.target.wants/org.tizen.dummyasm.service +%attr(0644,root,root) /usr/share/dbus-1/system-services/org.tizen.dummyasm.service +%{_libdir}/fido/asm/dummy_asm.json + +################################################################################# +# Fido Sample App + +%package -n org.tizen.FidoSample +Summary: Fido Sample App (Internal Dev) +Group: Account/Testing +#Requires: %{name} = %{version}-%{release} + +BuildRequires: cmake +BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-system-system-settings) +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(efl-extension) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(glib-2.0) >= 2.26 +BuildRequires: pkgconfig(gio-unix-2.0) +Requires: fido-client + +%description -n org.tizen.FidoSample +This is a program to test the Fido service internally. + +%files -n org.tizen.FidoSample +%defattr(-,root,root,-) +/usr/share/license/%{name} +%manifest org.tizen.FidoSample.manifest +/opt/usr/apps/org.tizen.FidoSample/bin/* +/opt/usr/apps/org.tizen.FidoSample/res/* +/opt/usr/apps/org.tizen.FidoSample/shared/res/* +/opt/share/packages/org.tizen.FidoSample.xml +##/opt/share/icons/default/small/org.tizen.FidoSample.png diff --git a/packaging/org.tizen.dummyasm.conf b/packaging/org.tizen.dummyasm.conf new file mode 100644 index 0000000..853906b --- /dev/null +++ b/packaging/org.tizen.dummyasm.conf @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/org.tizen.dummyasm.service b/packaging/org.tizen.dummyasm.service new file mode 100644 index 0000000..976d582 --- /dev/null +++ b/packaging/org.tizen.dummyasm.service @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.tizen.dummyasm +Exec=/usr/bin/dummyasm-service +User=system +Group=system diff --git a/packaging/org.tizen.fido.conf b/packaging/org.tizen.fido.conf new file mode 100644 index 0000000..12260bc --- /dev/null +++ b/packaging/org.tizen.fido.conf @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/org.tizen.fido.service b/packaging/org.tizen.fido.service new file mode 100644 index 0000000..32cc443 --- /dev/null +++ b/packaging/org.tizen.fido.service @@ -0,0 +1,8 @@ +[Unit] +Description=FIDO Service D-Bus + +[D-BUS Service] +Name=org.tizen.fido +Exec=/usr/bin/fido-service +User=system +Group=system diff --git a/packaging/org.tizen.fidosvcui.service b/packaging/org.tizen.fidosvcui.service new file mode 100644 index 0000000..7f83467 --- /dev/null +++ b/packaging/org.tizen.fidosvcui.service @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.tizen.fidosvcui +Exec=/usr/bin/fido-ui-service +User=system +Group=system diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt new file mode 100644 index 0000000..015a31e --- /dev/null +++ b/server/CMakeLists.txt @@ -0,0 +1,56 @@ +SET(SVC_DAEMON fido-service) + +INCLUDE(FindPkgConfig) +pkg_check_modules(SERVER_pkgs REQUIRED + dlog + glib-2.0 + gio-unix-2.0 + capi-base-common + json-glib-1.0 + capi-appfw-application + aul + libsoup-2.4 + capi-appfw-app-manager + openssl + bundle + cynara-client + cynara-session + cynara-creds-gdbus + libtzplatform-config +) + +FOREACH(flag ${SERVER_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(SERVER_SRCS + fido_server.c + fido_asm_plugin_manager.c + fido_uaf_policy_checker.c + fido_selection_ui_adaptor.c + ../common/fido_uaf_utils.c + ../common/fido_json_handler.c + ../common/fido_tlv_util.c + fido_app_id_handler.c + ../common/fido_b64_util.c + fido_privilege_checker.c +) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) + +ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_SOURCE_DIR}/common/fido-stub.c ${CMAKE_SOURCE_DIR}/common/fido-stub.h +WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/common/ +COMMAND gdbus-codegen --interface-prefix org.tizen. --generate-c-code fido-stub ${CMAKE_SOURCE_DIR}/common/dbus_interfaces/fido.xml +COMMENT "Generating FIDO GDBus stubs........................") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror") +SET(CMAKE_LDFLAGS "-Wl,-zdefs") + +ADD_EXECUTABLE(${SVC_DAEMON} ${SERVER_SRCS} ${CMAKE_SOURCE_DIR}/common/fido-stub.c) +ADD_DEPENDENCIES(${SVC_DAEMON} ${CMAKE_SOURCE_DIR}/common/fido-stub.h) +ADD_DEPENDENCIES(${SVC_DAEMON} ${CMAKE_SOURCE_DIR}/common/fido-stub.c) + +TARGET_LINK_LIBRARIES(${SVC_DAEMON} ${SERVER_pkgs_LDFLAGS}) + +INSTALL(TARGETS ${SVC_DAEMON} DESTINATION bin) + diff --git a/server/fido_app_id_handler.c b/server/fido_app_id_handler.c new file mode 100644 index 0000000..7046163 --- /dev/null +++ b/server/fido_app_id_handler.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fido_internal_types.h" +#include "fido_json_handler.h" +#include "fido_app_id_handler.h" +#include "fido_logs.h" + +#define _FREEDESKTOP_SERVICE "org.freedesktop.DBus" +#define _FREEDESKTOP_PATH "/org/freedesktop/DBus" +#define _FREEDESKTOP_INTERFACE "org.freedesktop.DBus" + +#define _MAX_NW_TIME_OUT 20 + +typedef struct _app_id_cb_data { + char *caller_app_id; + char *real_app_id; + _facet_id_cb cb; + void *user_data; +}_app_id_cb_data_t; + +static inline int +__read_proc(const char *path, char *buf, int size) +{ + int fd = 0; + int ret = 0; + + if (buf == NULL || path == NULL) { + _ERR("path and buffer is mandatory\n"); + return -1; + } + + fd = open(path, O_RDONLY); + if (fd < 0) { + _ERR("fd open error(%d)\n", fd); + return -1; + } + + ret = read(fd, buf, size - 1); + if (ret <= 0) { + _ERR("fd read error(%d)\n", fd); + close(fd); + return -1; + } else + buf[ret] = 0; + + close(fd); + + return ret; +} + +static char* +__get_appid_of_dbus_caller(GDBusMethodInvocation *invocation) +{ + pid_t remote_pid = 0; + GError *error = NULL; + GDBusConnection *connection = NULL; + GVariant *response = NULL; + guint32 upid; + const gchar *sender = NULL; + + sender = g_dbus_method_invocation_get_sender (invocation); + if (!sender) { + _ERR("Failed to get sender"); + return NULL; + } + + connection = g_dbus_method_invocation_get_connection(invocation); + if (connection == NULL) { + _ERR("Failed to open connection for the invocation"); + return NULL; + } + + error = NULL; + response = g_dbus_connection_call_sync (connection, + _FREEDESKTOP_SERVICE, _FREEDESKTOP_PATH, + _FREEDESKTOP_INTERFACE, "GetConnectionUnixProcessID", + g_variant_new ("(s)", sender), ((const GVariantType *) "(u)"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + //g_object_unref (connection); + + if (response == NULL) { + _ERR("Failed to get caller id [%s]", error->message); + g_error_free (error); + return NULL; + } + + g_variant_get (response, "(u)", &upid); + _INFO("Remote msg-bus peer service=%s pid=%u", sender, upid); + remote_pid = (pid_t) upid; + + g_variant_unref (response); + + char *app_id = NULL; + int ret = app_manager_get_app_id(remote_pid, &app_id); + + if (app_id == NULL) { + _ERR("app_manager_get_app_id for %d failed = %d", remote_pid, ret); + + /* Exception case : Daemons will not have app-ids, for them path will be set : /usr/bin/sample-service */ + char buf[128]; + int ret = 0; + + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", upid); + ret = __read_proc(buf, buf, sizeof(buf)); + if (ret <= 0) { + _ERR("No proc directory (%d)\n", upid); + return NULL; + } + + _INFO("Caller=[%s]", buf); + + app_id = strdup(buf); + } + + + return app_id; +} + +static void +__soup_cb(SoupSession *session, SoupMessage *msg, gpointer user_data) +{ + _INFO("__soup_cb"); + + if (user_data == NULL) + return; + + _app_id_cb_data_t *cb_data = (_app_id_cb_data_t*)user_data; + + GList *app_id_list = NULL; + char *real_app_id = NULL; + + int error_code = FIDO_ERROR_UNTRUSTED_FACET_ID; + + SoupBuffer *request = NULL; + + _INFO("status_code = [%d]", msg->status_code); + + CATCH_IF_FAIL_X(msg->status_code == SOUP_STATUS_OK, error_code = FIDO_ERROR_UNTRUSTED_FACET_ID); + + request = soup_message_body_flatten(msg->response_body); + app_id_list = _uaf_parser_parse_trusted_facets(request->data); + + soup_buffer_free(request); + request = NULL; + + if (app_id_list == NULL) + error_code = FIDO_ERROR_UNTRUSTED_FACET_ID; + + GList *app_id_list_iter = app_id_list; + while (app_id_list_iter != NULL) { + char *id = (char *)(app_id_list_iter->data); + SoupURI *parsed_uri = soup_uri_new(id); + if (parsed_uri == NULL) + if (strcmp(cb_data->caller_app_id, id) == 0) { + real_app_id = strdup(id); + error_code = FIDO_ERROR_NONE; + break; + } + soup_uri_free(parsed_uri); + + app_id_list_iter = app_id_list_iter->next; + } + +CATCH: + (cb_data->cb)(error_code, real_app_id, cb_data->user_data); + + if (app_id_list != NULL) + g_list_free_full(app_id_list, free); + + SAFE_DELETE(real_app_id); + SAFE_DELETE(cb_data->real_app_id); + SAFE_DELETE(cb_data->caller_app_id); + SAFE_DELETE(cb_data); +} + +static void +_free_app_id_cb_data(_app_id_cb_data_t* data) +{ + _INFO(""); + + RET_IF_FAIL_VOID(data != NULL); + + SAFE_DELETE(data->real_app_id); + SAFE_DELETE(data->caller_app_id); + + SAFE_DELETE(data); + + _INFO(""); +} + +static gboolean +__timer_expired(gpointer data) +{ + _INFO("__timer_expired"); + _app_id_cb_data_t *cb_data = (_app_id_cb_data_t*)data; + (cb_data->cb)(FIDO_ERROR_NONE, cb_data->real_app_id, cb_data->user_data); + + _free_app_id_cb_data(cb_data); + + return FALSE; +} + +int +_verify_and_get_facet_id(const char *uaf_app_id, GDBusMethodInvocation *invocation, _facet_id_cb cb, void *user_data) +{ + _INFO("_verify_and_get_facet_id"); + + char *app_id = __get_appid_of_dbus_caller(invocation); + if (app_id == NULL) { + return FIDO_ERROR_PERMISSION_DENIED; + } + + _app_id_cb_data_t *cb_data = (_app_id_cb_data_t*)calloc(1, sizeof(_app_id_cb_data_t)); + if (cb_data == NULL) + return FIDO_ERROR_OUT_OF_MEMORY; + + cb_data->caller_app_id = app_id; + cb_data->cb = cb; + cb_data->user_data = user_data; + + if (uaf_app_id == NULL) { + cb_data->real_app_id = strdup(app_id); + g_timeout_add(2, __timer_expired, cb_data); + return FIDO_ERROR_NONE; + } + + + SoupURI *parsed_uri = soup_uri_new(uaf_app_id); + + if (parsed_uri == NULL) { + + if (strcmp(app_id, uaf_app_id) == 0) { + cb_data->real_app_id = strdup(uaf_app_id); + g_timeout_add(2, __timer_expired, cb_data); + return FIDO_ERROR_NONE; + } + else { + _free_app_id_cb_data(cb_data); + return FIDO_ERROR_PERMISSION_DENIED; + } + } + + const char *scheme = soup_uri_get_scheme(parsed_uri); + if (scheme == NULL) { + _free_app_id_cb_data(cb_data); + return FIDO_ERROR_INVALID_PARAMETER; + } + + if (strcmp(SOUP_URI_SCHEME_HTTPS, scheme) != 0) { + _free_app_id_cb_data(cb_data); + return FIDO_ERROR_INVALID_PARAMETER; + } + + _INFO("%s", uaf_app_id); + + SoupMessage *soup_message = soup_message_new_from_uri ("GET", parsed_uri); + + soup_uri_free(parsed_uri); + + SoupSession *session = soup_session_new_with_options( + SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_RESOLVER_DEFAULT, + SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE, + SOUP_SESSION_TIMEOUT, _MAX_NW_TIME_OUT, + NULL); + + bool ssl_strict = FALSE;//changed to make sure https cert errors dont occur, only for testing + g_object_set(session, "ssl-strict", ssl_strict, NULL); + + soup_session_queue_message(session, soup_message, __soup_cb, cb_data); + + _INFO("Added in soup_session_queue_message"); + + return FIDO_ERROR_NONE; +} diff --git a/server/fido_app_id_handler.h b/server/fido_app_id_handler.h new file mode 100644 index 0000000..19e307d --- /dev/null +++ b/server/fido_app_id_handler.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __FIDO_APP_ID_HANDLER_H__ +#define __FIDO_APP_ID_HANDLER_H__ + +#include +#include + +typedef void (*_facet_id_cb) (int eror_code, const char *facet_id, void *user_data); + +int _verify_and_get_facet_id(const char *uaf_app_id, GDBusMethodInvocation *invocation, _facet_id_cb cb, void *user_data); + +#endif /* __FIDO_APP_ID_HANDLER_H__ */ diff --git a/server/fido_asm_plugin_manager.c b/server/fido_asm_plugin_manager.c new file mode 100644 index 0000000..e61e2a2 --- /dev/null +++ b/server/fido_asm_plugin_manager.c @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "fido_logs.h" +#include "fido_uaf_types.h" +#include "fido_internal_types.h" +#include "fido_json_handler.h" +#include "fido_internal_types.h" + +#include "fido_asm_plugin_manager.h" + +#define _ASM_CONF_DIR_PATH "/usr/lib/fido/asm/" + +typedef struct _asm_ipc_cb_data { + _asm_ipc_response_cb cb; + void *user_data; +} _asm_ipc_cb_data_t; + +typedef struct _asm_ipc_discover_cb_data { + _asm_plugin_discover_response_cb cb; + GList *asm_proxy_list_iter; + void *user_data; + GList *asm_resp_list; +} _asm_ipc_discover_cb_data_t; + +static GHashTable *asm_proxy_table = NULL; +static GFileMonitor *__monitor = NULL; + +static GDBusConnection * +__get_dbus_connection(void) +{ + GError *error = NULL; + + GDBusConnection *dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + + if (dbus_conn == NULL) { + _ERR("Unable to connect to dbus: %s", error->message); + g_clear_error(&error); + } + + return dbus_conn; +} + +static GDBusProxy* +__get_dbus_proxy(const char *dbus_name, const char *obj_path, + const char *intf_name) +{ + GDBusConnection *conn = __get_dbus_connection(); + if (conn == NULL) + return NULL; + + GError *err = NULL; + + GDBusProxy *dbus_proxy = g_dbus_proxy_new_sync(conn, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + dbus_name, + obj_path, + intf_name, + NULL, + &err); + + if (err != NULL) + _ERR("g_dbus_proxy_new_sync failed [%d][%s]", err->code, err->message); + + return dbus_proxy; +} + +static void +__free_asm_proxy_data(gpointer data) +{ + if (data != NULL) { + _fido_asm_proxy_t *proxy = data; + + SAFE_DELETE(proxy->bin_path); + SAFE_DELETE(proxy->dbus_info); + SAFE_DELETE(proxy->dbus_interface_name); + SAFE_DELETE(proxy->dbus_method_name); + SAFE_DELETE(proxy->dbus_obj_path); + SAFE_DELETE(proxy->vendor); + + SAFE_DELETE(proxy); + } + + +} + +static int +__load_plugins(const char *path) +{ + RET_IF_FAIL(path != NULL, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR); + + if (asm_proxy_table != NULL) { + g_hash_table_destroy(asm_proxy_table); + asm_proxy_table = NULL; + } + + asm_proxy_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, _free_fido_asm_proxy); + + DIR *dir; + struct dirent *entry; + + dir = opendir(path); + if (dir == NULL) { + + _ERR("Could not open [%s] path = [%s]", path, strerror(errno)); + return FIDO_ERROR_PERMISSION_DENIED; + } + + bool is_asm_found = false; + + _INFO("Loading ASM conf files"); + + while ((entry = readdir(dir)) != NULL) { + if (entry->d_type == DT_REG) { + char *conf_file_name = entry->d_name; + if (conf_file_name != NULL) { + char conf_file_name_full[128] = {0, }; + /*TODO make safe size*/ + snprintf(conf_file_name_full, 127, "%s%s", _ASM_CONF_DIR_PATH, conf_file_name); + _INFO("Processing [%s]", conf_file_name_full); + _fido_asm_proxy_t *asm_proxy = _parse_asm_conf_file(conf_file_name_full); + if (asm_proxy != NULL) { + asm_proxy->dbus_proxy = __get_dbus_proxy(asm_proxy->dbus_info, asm_proxy->dbus_obj_path, + asm_proxy->dbus_interface_name); + if (asm_proxy->dbus_proxy != NULL) { + is_asm_found = true; + + asm_proxy->asm_id = strdup(conf_file_name); + g_hash_table_insert(asm_proxy_table, strdup(conf_file_name), asm_proxy); + } + else { + _ERR("Failed to get dbus proxy for the ASM"); + __free_asm_proxy_data((gpointer)asm_proxy); + } + } + + } + } + } + + closedir(dir); + + if (is_asm_found == false) + return FIDO_ERROR_NOT_SUPPORTED; + + return FIDO_ERROR_NONE; +} + +static void +__plugin_changed_cb(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, + void* user_data) +{ + int ret = __load_plugins(_ASM_CONF_DIR_PATH); + _INFO("__load_plugins=[%d]", ret); +} + +static void +__set_up_watcher(const char *watch_path) +{ + if ((watch_path == NULL) + || (strlen(watch_path) == 0)) + return; + + GFile* file = g_file_new_for_path(watch_path); + + if (__monitor != NULL) + g_object_unref(__monitor); + + __monitor = g_file_monitor(file, G_FILE_MONITOR_NONE, NULL, NULL); + g_object_unref(file); + + if (__monitor == NULL) + return; + + g_signal_connect(__monitor, "changed", G_CALLBACK(__plugin_changed_cb), NULL); +} + +int +_asm_plugin_mgr_init(void) +{ + + _INFO("_asm_plugin_mgr_init start"); + + int ret = __load_plugins(_ASM_CONF_DIR_PATH); + _INFO("__load_plugins=[%d]", ret); + + __set_up_watcher(_ASM_CONF_DIR_PATH); + + /*Ignored load_plugins error, since ASM might get installed later*/ + return FIDO_ERROR_NONE; +} + +void +_asm_plugin_mgr_destroy(void) +{ + if (asm_proxy_table != NULL) { + g_hash_table_destroy(asm_proxy_table); + asm_proxy_table = NULL; + } + if (__monitor != NULL) + g_object_unref(__monitor); +} + +static void +__discover_cb_internal(int error_code, const char *asm_response_json, void *user_data) +{ + _asm_ipc_discover_cb_data_t *cb_data = user_data; + + _asm_discover_response_t *response_info = calloc(1, sizeof(_asm_discover_response_t)); + response_info->error_code = error_code; + if (asm_response_json != NULL) + response_info->asm_response_json = strdup(asm_response_json); + + _fido_asm_proxy_t *asm_proxy = (_fido_asm_proxy_t*)(cb_data->asm_proxy_list_iter->data); + response_info->asm_id = strdup(asm_proxy->asm_id); + + cb_data->asm_resp_list = g_list_append(cb_data->asm_resp_list, response_info); + + cb_data->asm_proxy_list_iter = g_list_next(cb_data->asm_proxy_list_iter); + if (cb_data->asm_proxy_list_iter == NULL) { + _INFO("All ASM processing finished"); + + cb_data->asm_resp_list = g_list_first(cb_data->asm_resp_list); + (cb_data->cb)(cb_data->asm_resp_list, cb_data->user_data); + + cb_data->asm_proxy_list_iter = g_list_first(cb_data->asm_proxy_list_iter); + g_list_free(cb_data->asm_proxy_list_iter); + + SAFE_DELETE(cb_data); + } + else { + + _fido_asm_proxy_t *asm_proxy = (_fido_asm_proxy_t*)(cb_data->asm_proxy_list_iter->data); + int ret = _asm_ipc_send(asm_proxy->asm_id, _GET_INFO_ASM_REQUEST_JSON, __discover_cb_internal, cb_data); + if (ret != FIDO_ERROR_NONE) + __discover_cb_internal(ret, NULL, user_data); + } + +} + +int +_asm_plugin_mgr_discover_all(_asm_plugin_discover_response_cb cb, void *user_data) +{ + if (asm_proxy_table == NULL + || g_hash_table_size(asm_proxy_table) <= 0) { + _ERR("No ASM found"); + return FIDO_ERROR_NOT_SUPPORTED; + } + + _asm_ipc_discover_cb_data_t *cb_data = calloc(1, sizeof(_asm_ipc_discover_cb_data_t)); + if (cb_data == NULL) + return -1; + + cb_data->cb = cb; + cb_data->asm_proxy_list_iter = g_hash_table_get_values(asm_proxy_table); + + cb_data->user_data = user_data; + + _fido_asm_proxy_t *asm_proxy = (_fido_asm_proxy_t*)(cb_data->asm_proxy_list_iter->data); + + return _asm_ipc_send(asm_proxy->asm_id, _GET_INFO_ASM_REQUEST_JSON, __discover_cb_internal, cb_data); +} + +static void +_on_asm_dbus_reply(GObject *proxy, GAsyncResult *res, gpointer user_data) +{ + _INFO("_on_asm_dbus_reply"); + + GError *dbus_err = NULL; + + if (user_data == NULL) { + _ERR("Can not proceed since callback data is NULL"); + return; + } + + _asm_ipc_cb_data_t *cb_data = (_asm_ipc_cb_data_t *)user_data; + if (cb_data == NULL) { + _ERR("Can not proceed since callback data is NULL"); + return; + } + + if (cb_data->cb == NULL) { + _ERR("Can not proceed since callback data's cb part is NULL"); + return; + } + + int tizen_err = FIDO_ERROR_NONE; + char *asm_response_json = NULL; + + GError *error = NULL; + + /*For dereg request, ASM does not send any reponse, so this is not error for dereg*/ + GVariant *dbus_resp = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error); + if (dbus_resp == NULL) { + _ERR("g_dbus_proxy_call_finish failed with [%d][%s]", error->code, error->message); + (cb_data->cb)(FIDO_ERROR_PERMISSION_DENIED, NULL, cb_data->user_data); + + SAFE_DELETE(cb_data); + + return; + } + + g_variant_get(dbus_resp, "(is)", + &tizen_err, + &asm_response_json); + + + g_clear_error(&dbus_err); + + if (asm_response_json != NULL) + _INFO("asm_response_json=[%s]", asm_response_json); + + (cb_data->cb)(tizen_err, asm_response_json, cb_data->user_data); + + if (dbus_resp != NULL) + g_variant_unref(dbus_resp); + + SAFE_DELETE(cb_data); +} + +static char* +__get_asm_req_dbus_method_name(const char *intf_name, const char *dbus_method_name) +{ + char *method_name = (char *)calloc(1, 128); + if (method_name == NULL) + return NULL; + + snprintf(method_name, 127, "%s.%s", intf_name, dbus_method_name); + + return method_name; +} + +int +_asm_ipc_send(const char *asm_id, const char *asm_request, _asm_ipc_response_cb cb, void *user_data) +{ + _INFO("asm_request=[%s]", asm_request); + + if (asm_id == NULL) { + _ERR("dbus proxy failed"); + return FIDO_ERROR_NOT_SUPPORTED; + } + + _fido_asm_proxy_t *asm_proxy = g_hash_table_lookup(asm_proxy_table, asm_id); + if (asm_proxy == NULL) { + _ERR("dbus proxy failed"); + return FIDO_ERROR_NOT_SUPPORTED; + } + + _INFO("For=[%s]", asm_id); + + if (asm_proxy->dbus_info != NULL) + _INFO("For DBUS = [%s]", asm_proxy->dbus_info); + + _asm_ipc_cb_data_t *cb_data = (_asm_ipc_cb_data_t*)calloc(1, sizeof(_asm_ipc_cb_data_t)); + if (cb_data == NULL) + return -1; + + cb_data->cb = cb; + cb_data->user_data = user_data; + + char *method_name = __get_asm_req_dbus_method_name(asm_proxy->dbus_interface_name, + asm_proxy->dbus_method_name); + if (method_name == NULL) { + + SAFE_DELETE(cb_data); + return FIDO_ERROR_OUT_OF_MEMORY; + } + + g_dbus_proxy_call(asm_proxy->dbus_proxy, + method_name, + g_variant_new ("(s)", + asm_request), + G_DBUS_CALL_FLAGS_NONE, + _DBUS_TIMEOUT_INFINITE, + NULL, + _on_asm_dbus_reply, + cb_data); + + SAFE_DELETE(method_name); + + return 0; +} + +char * +_asm_ipc_send_sync(const char *asm_id, const char *asm_req) +{ + _INFO("_asm_ipc_send_sync"); + + if (asm_id == NULL) { + _ERR("dbus proxy failed"); + return NULL; + } + + _INFO("For=[%s]", asm_id); + + _fido_asm_proxy_t *asm_proxy = g_hash_table_lookup(asm_proxy_table, asm_id); + if (asm_proxy == NULL) { + _ERR("dbus proxy failed"); + return NULL; + } + + if (asm_proxy->dbus_info != NULL) + _INFO("For DBUS = [%s]", asm_proxy->dbus_info); + + int tz_err = FIDO_ERROR_NONE; + char *asm_res_json = NULL; + + GError *error = NULL; + GVariant *_ret; + + char *method_name = __get_asm_req_dbus_method_name(asm_proxy->dbus_interface_name, + asm_proxy->dbus_method_name); + + if (method_name == NULL) + return NULL; + + _ret = g_dbus_proxy_call_sync(asm_proxy->dbus_proxy, + method_name, + g_variant_new ("(s)", + asm_req), + G_DBUS_CALL_FLAGS_NONE, + _DBUS_TIMEOUT_USE_DEFAULT, + NULL, + &error); + + if (error != NULL) + _ERR("g_dbus_proxy_call_sync failed [%s]", error->message); + else + _INFO("g_dbus_proxy_call_sync success"); + + if (_ret == NULL) + goto CATCH; + + g_variant_get (_ret, "(is)", &tz_err, &asm_res_json); + if (asm_res_json != NULL) + _INFO("ASM returned = %s", asm_res_json); + + //g_variant_unref (_ret); + +CATCH: + return asm_res_json; +} diff --git a/server/fido_asm_plugin_manager.h b/server/fido_asm_plugin_manager.h new file mode 100644 index 0000000..ac7a62a --- /dev/null +++ b/server/fido_asm_plugin_manager.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __FIDO_ASM_PLUGIN_MGR_H__ +#define __FIDO_ASM_PLUGIN_MGR_H__ + +#include +#include +#include "fido_internal_types.h" + +int _asm_plugin_mgr_init(void); + +void _asm_plugin_mgr_destroy(void); + +/*List of _asm_discover_response_t*/ +typedef void (*_asm_plugin_discover_response_cb) (GList *asm_disc_resp_list, void * user_data); +int _asm_plugin_mgr_discover_all(_asm_plugin_discover_response_cb cb, void *user_data); + +typedef void (*_asm_ipc_response_cb) (int eror_code, const char *asm_response_json, void * user_data); + +int _asm_ipc_send(const char *asm_id, const char *asm_request, _asm_ipc_response_cb cb, void *user_data); + +char *_asm_ipc_send_sync(const char *asm_id, const char *asm_req); + +#endif /* __FIDO_ASM_PLUGIN_MGR_H__ */ diff --git a/server/fido_privilege_checker.c b/server/fido_privilege_checker.c new file mode 100644 index 0000000..528c8a0 --- /dev/null +++ b/server/fido_privilege_checker.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "fido_privilege_checker.h" +#include "fido_logs.h" + +#include +#include +#include + +#define _DISABLE_PRIV_CHECK + +static cynara *__cynara = NULL; + +static guint +_get_client_pid(GDBusMethodInvocation* invoc) +{ + const char *name = NULL; + name = g_dbus_method_invocation_get_sender(invoc); + if (name == NULL) + { + _ERR("g_dbus_method_invocation_get_sender failed"); + return -1; + } + _INFO("sender=[%s]", name); + + + guint pid = -1; + GError *error = NULL; + GVariant *_ret; + + _INFO("calling GetConnectionUnixProcessID"); + + GDBusConnection* conn = g_dbus_method_invocation_get_connection(invoc); + _ret = g_dbus_connection_call_sync(conn, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetConnectionUnixProcessID", + g_variant_new("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + + if (_ret != NULL) { + g_variant_get(_ret, "(u)", &pid); + g_variant_unref(_ret); + } + + _INFO("process Id = [%u]", pid); + return pid; +} + +static int +__check_privilege_by_cynara(const char *client, const char *session, const char *user, const char *privilege) +{ + int ret; + char err_buf[128] = {0,}; + + ret = cynara_check(__cynara, client, session, user, privilege); + switch (ret) { + case CYNARA_API_ACCESS_ALLOWED: + _DBG("cynara_check success"); + return FIDO_ERROR_NONE; + + case CYNARA_API_ACCESS_DENIED: + _ERR("cynara_check permission deined, privilege=%s, error = CYNARA_API_ACCESS_DENIED", privilege); + return FIDO_ERROR_PERMISSION_DENIED; + + default: + cynara_strerror(ret, err_buf, sizeof(err_buf)); + _ERR("cynara_check error : %s, privilege=%s, ret = %d", err_buf, privilege, ret); + return FIDO_ERROR_PERMISSION_DENIED; + } +} + +static int +__get_information_for_cynara_check(GDBusMethodInvocation *invocation, char **client, char **user, char **session) +{ + GDBusConnection *gdbus_conn = NULL; + char* sender = NULL; + int ret = -1; + + gdbus_conn = g_dbus_method_invocation_get_connection(invocation); + if(gdbus_conn == NULL) { + _ERR("g_dbus_method_invocation_get_connection failed"); + return -1; + } + + sender = (char*) g_dbus_method_invocation_get_sender(invocation); + if (sender == NULL) { + _ERR("g_dbus_method_invocation_get_sender failed"); + return -1; + } + + ret = cynara_creds_gdbus_get_user(gdbus_conn, sender, USER_METHOD_DEFAULT, user); + if (ret != CYNARA_API_SUCCESS) { + _ERR("cynara_creds_gdbus_get_user failed, ret = %d", ret); + return -1; + } + + ret = cynara_creds_gdbus_get_client(gdbus_conn, sender, CLIENT_METHOD_DEFAULT, client); + if (ret != CYNARA_API_SUCCESS) { + _ERR("cynara_creds_gdbus_get_client failed, ret = %d", ret); + return -1; + } + + guint pid = _get_client_pid(invocation); + _INFO("client Id = [%u]", pid); + + *session = cynara_session_from_pid(pid); + if (*session == NULL) { + _ERR("cynara_session_from_pid failed"); + return -1; + } + return FIDO_ERROR_NONE; +} + +bool +is_allowed_to_call(GDBusMethodInvocation *invocation, const char* privilege) +{ + int ret = -1; + + if (__cynara == NULL) { + ret = cynara_initialize(&__cynara, NULL); + if(ret != CYNARA_API_SUCCESS) { + _ERR("CYNARA Initialization fail"); + return false; + } + } + + char *client = NULL; + char *session = NULL; + char *user = NULL; + + ret = __get_information_for_cynara_check(invocation, &client, &user, &session); + if ( ret != FIDO_ERROR_NONE) { + _ERR("__get_information_for_cynara_check failed"); + g_free(client); + g_free(user); + SAFE_DELETE(session); + + return false; + } + + ret = __check_privilege_by_cynara(client, session, user, privilege); + + /*TODO enable after smack is defined*/ +#ifndef _DISABLE_PRIV_CHECK + if ( ret != FIDO_ERROR_NONE) { + _ERR("__check_privilege_by_cynara failed, ret = %d", ret); + g_free(client); + g_free(user); + SAFE_DELETE(session); + + return false; + } +#endif + g_free(client); + g_free(user); + SAFE_DELETE(session); + + return true; +} diff --git a/server/fido_privilege_checker.h b/server/fido_privilege_checker.h new file mode 100644 index 0000000..b24447d --- /dev/null +++ b/server/fido_privilege_checker.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef FIDO_PRIVILEGE_CHECKER_H +#define FIDO_PRIVILEGE_CHECKER_H + +#include +#include "fido_internal_types.h" + +#define _FIDO_CLIENT_PRIVILEGE "http://tizen.org/privilege/fido" + +bool is_allowed_to_call(GDBusMethodInvocation *invocation, const char* privilege); + +#endif // FIDO_PRIVILEGE_CHECKER_H diff --git a/server/fido_selection_ui_adaptor.c b/server/fido_selection_ui_adaptor.c new file mode 100644 index 0000000..17ae88b --- /dev/null +++ b/server/fido_selection_ui_adaptor.c @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fido_selection_ui_adaptor.h" +#include "fido_uaf_types.h" +#include "fido_logs.h" +#include "fido-stub.h" +#include "fido_internal_types.h" + +#define _UI_LAUNCH_RETRY_COUNT 5 +#define _UI_SVC_TERMINATE_TIMEOUT 2000 + +#define _FREEDESKTOP_SERVICE "org.freedesktop.DBus" +#define _FREEDESKTOP_PATH "/org/freedesktop/DBus" +#define _FREEDESKTOP_INTERFACE "org.freedesktop.DBus" + +static GQueue *_ui_q = NULL; +static int __ui_svc_pid = -1; + +static int _process_ui_selection_queue(void); + +typedef struct _ui_response_cb_data { + GList *auth_list; + _ui_response_cb cb; + void *user_data; +} _ui_response_cb_data_t; + +static void +__free_ui_auth_data(gpointer data) +{ + RET_IF_FAIL_VOID(data != NULL); + + _ui_auth_data_t *auth_data = data; + + SAFE_DELETE(auth_data->asm_id); + SAFE_DELETE(auth_data->auth_index); + SAFE_DELETE(auth_data->label); + + SAFE_DELETE(auth_data); +} + +static void +__free_ui_response_cb_data(_ui_response_cb_data_t *data) +{ + RET_IF_FAIL_VOID(data != NULL); + + if (data->auth_list != NULL) + g_list_free_full(data->auth_list, __free_ui_auth_data); + + SAFE_DELETE(data); +} + +static GQueue * +_get_ui_queue(void) +{ + if (_ui_q != NULL) + return _ui_q; + + _ui_q = g_queue_new(); + if (_ui_q == NULL) { + _ERR("Out of memory"); + } + + return _ui_q; +} + +_ui_auth_data_t* +_compose_json_ui_out(const char *response_json) +{ + _INFO("_compose_json_ui_out %s", response_json); + + char *ui_response_json = strdup(response_json); + _ui_auth_data_t *ui_auth_data = NULL; + GError *parse_err = NULL; + JsonParser *parser = NULL; + JsonNode *root = NULL; + JsonObject *obj = NULL; + + parser = json_parser_new(); + if (!parser) { + _ERR("json_parser_new failed"); + goto CATCH; + } + + json_parser_load_from_data(parser, ui_response_json, -1, &parse_err); + if (parse_err != NULL) { + _ERR("json parse failure"); + goto CATCH; + } + + root = json_parser_get_root(parser); + if (!root) { + _ERR("json_parser_get_root() failed"); + goto CATCH; + } + + obj = json_node_get_object(root); + if (!obj) { + _ERR("json_node_get_object() failed"); + goto CATCH; + } + + const char *asm_id = json_object_get_string_member(obj, UI_DATA_ASM_ID); + if (!asm_id) { + _ERR("json_object_get_string_member() failed"); + goto CATCH; + } + + const char *auth_idx = NULL; + auth_idx = json_object_get_string_member(obj, UI_DATA_AUTH_INDEX); + if (!auth_idx) { + _ERR("json_object_get_string_member() failed"); + goto CATCH; + } + + const char *label = NULL; + label = json_object_get_string_member(obj, UI_DATA_LABEL); + if (!label) { + _ERR("json_object_get_string_member() failed"); + goto CATCH; + } + + int att = -1; + att = json_object_get_int_member(obj, UI_DATA_ATT_TYPE); + + ui_auth_data = (_ui_auth_data_t *) calloc(1, sizeof(_ui_auth_data_t)); + if (ui_auth_data == NULL) + { + _ERR("Out of memory"); + goto CATCH; + } + + ui_auth_data->asm_id = strdup(asm_id); + ui_auth_data->auth_index = strdup(auth_idx); + ui_auth_data->label = strdup(label); + ui_auth_data->att_type = att; + +CATCH: + if (parse_err != NULL) { + g_error_free(parse_err); + parse_err = NULL; + } + + if (root != NULL) { + json_node_free(root); + root = NULL; + } + + if (obj != NULL) { + g_object_unref(obj); + obj = NULL; + } + + SAFE_DELETE(ui_response_json); + + return ui_auth_data; +} + +char * +_compose_json_ui_in(GList *auth_list) +{ + _INFO("_compose_json_ui_in"); + + char *json_ui_arr = NULL; + JsonGenerator *generator = NULL; + JsonNode *root_node = NULL; + JsonArray *ui_arr = NULL; + + generator = json_generator_new(); + if(generator == NULL) { + _ERR("json_generator_new is NULL"); + goto CATCH; + } + + root_node = json_node_new(JSON_NODE_ARRAY); + if (root_node == NULL) { + _ERR("json_node_new is NULL"); + goto CATCH; + } + + ui_arr = json_array_new(); + if (ui_arr == NULL) { + _ERR("json_array_new is NULL"); + goto CATCH; + } + + json_node_take_array(root_node, ui_arr); + json_generator_set_root(generator, root_node); + + GList *auth_list_iter = auth_list; + while (auth_list_iter != NULL) { + _ui_auth_data_t *ui_data = (_ui_auth_data_t *)(auth_list_iter->data); + + if (ui_data) { + JsonObject *obj = json_object_new(); + + if (ui_data->asm_id != NULL) + json_object_set_string_member(obj, UI_DATA_ASM_ID, ui_data->asm_id); + + json_object_set_string_member(obj, UI_DATA_AUTH_INDEX, ui_data->auth_index); + if (ui_data->label != NULL) + json_object_set_string_member(obj, UI_DATA_LABEL, ui_data->label); + json_object_set_int_member(obj, UI_DATA_ATT_TYPE, ui_data->att_type); + + json_array_add_object_element(ui_arr, obj); + } + + auth_list_iter = auth_list_iter->next; + } + + json_ui_arr = json_generator_to_data(generator, NULL); + +CATCH: + if (generator != NULL) { + g_object_unref(generator); + generator = NULL; + } + + if (root_node != NULL) { + json_node_free(root_node); + root_node = NULL; + } + + if (ui_arr != NULL) { + json_array_unref(ui_arr); + ui_arr = NULL; + } + + return json_ui_arr; +} + +//static int +//__iterfunc(const aul_app_info *info, void *data) +//{ +// if (strcmp(info->pkg_name, _UI_SVC_PACKAGE) == 0) { +// aul_terminate_pid(info->pid); +// _INFO("After aul_terminate_pid"); +// return false; +// } +// return true; +//} + +static void +__terminate_ui_svc(void) +{ + _INFO("Killing inactive UI Service [%d]", __ui_svc_pid); + + if (__ui_svc_pid > 0) + aul_terminate_pid(__ui_svc_pid); + + __ui_svc_pid = -1; +} + +static gboolean +__timer_expired(gpointer data) +{ + if (g_queue_is_empty(_ui_q) == TRUE) + __terminate_ui_svc(); + + return FALSE; +} + +static void +__start_ui_svc_term_timer(void) +{ + g_timeout_add(_UI_SVC_TERMINATE_TIMEOUT, __timer_expired, NULL); +} + +static int +__launch_svc_ui(bundle *ui_req) +{ + int i = 0; + for (; i < _UI_LAUNCH_RETRY_COUNT; i++) { + if (__ui_svc_pid < 0) + __ui_svc_pid = aul_launch_app(_UI_SVC_PACKAGE, ui_req); + else { + aul_terminate_pid(__ui_svc_pid); + __ui_svc_pid = -1; + + __ui_svc_pid = aul_launch_app(_UI_SVC_PACKAGE, ui_req); + } + + _INFO("fido svc pid = [%d]", __ui_svc_pid); + + if (__ui_svc_pid > 0) + return FIDO_ERROR_NONE; + } + return FIDO_ERROR_UNKNOWN; +} + +static int +_process_ui_selection_queue(void) +{ + _INFO("_process_ui_selection_queue"); + GQueue *q = _ui_q; + RET_IF_FAIL(q, FIDO_ERROR_INVALID_PARAMETER); + + if (g_queue_is_empty(q) == true) + return FIDO_ERROR_NONE; + + _ui_response_cb_data_t *ui_res_data = (_ui_response_cb_data_t *)(g_queue_peek_head(q)); + RET_IF_FAIL(ui_res_data, FIDO_ERROR_INVALID_PARAMETER); + + char *ui_data = _compose_json_ui_in(ui_res_data->auth_list); + if (ui_data == NULL) { + ui_res_data->cb(FIDO_ERROR_OUT_OF_MEMORY, NULL, ui_res_data->user_data); + g_queue_pop_head(q); + return FIDO_ERROR_OUT_OF_MEMORY; + } + + _INFO("Sending to UI SVC"); + _INFO("%s", ui_data); + + bundle *ui_req = bundle_create(); + bundle_add_str(ui_req, _UI_IPC_KEY_REQ, ui_data); + + return __launch_svc_ui(ui_req); +} + +int +_auth_ui_selector_send(GList *auth_list, _ui_response_cb cb, void *user_data) +{ + _INFO("_auth_ui_selector_send"); + RET_IF_FAIL(auth_list, FIDO_ERROR_INVALID_PARAMETER); + + _ui_response_cb_data_t *ui_cb_data = (_ui_response_cb_data_t *) calloc(1, sizeof(_ui_response_cb_data_t)); + RET_IF_FAIL(ui_cb_data, FIDO_ERROR_OUT_OF_MEMORY); + + ui_cb_data->auth_list = auth_list; + ui_cb_data->cb = cb; + ui_cb_data->user_data = user_data; + + GQueue *q = _get_ui_queue(); + if (q == NULL) { + __free_ui_response_cb_data(ui_cb_data); + return FIDO_ERROR_OUT_OF_MEMORY; + } + + g_queue_push_tail(q, ui_cb_data); + _INFO("Q len=[%d]", g_queue_get_length(q)); + + if (g_queue_get_length(q) == 1) + _process_ui_selection_queue(); + + return FIDO_ERROR_NONE; +} + +static inline int +__read_proc(const char *path, char *buf, int size) +{ + int fd = 0; + int ret = 0; + + if (buf == NULL || path == NULL) { + _ERR("path and buffer is mandatory\n"); + return -1; + } + + fd = open(path, O_RDONLY); + if (fd < 0) { + _ERR("fd open error(%d)\n", fd); + return -1; + } + + ret = read(fd, buf, size - 1); + if (ret <= 0) { + _ERR("fd read error(%d)\n", fd); + close(fd); + return -1; + } else + buf[ret] = 0; + + close(fd); + + return ret; +} + +static char* +__get_proc_path_of_dbus_caller(GDBusMethodInvocation *invocation) +{ + //pid_t remote_pid = 0; + GError *error = NULL; + GDBusConnection *connection = NULL; + GVariant *response = NULL; + guint32 upid; + const gchar *sender = NULL; + + sender = g_dbus_method_invocation_get_sender (invocation); + if (!sender) { + _ERR("Failed to get sender"); + return NULL; + } + + connection = g_dbus_method_invocation_get_connection(invocation); + if (connection == NULL) { + _ERR("Failed to open connection for the invocation [%s]", error->message); + g_error_free (error); + return NULL; + } + + error = NULL; + response = g_dbus_connection_call_sync (connection, + _FREEDESKTOP_SERVICE, _FREEDESKTOP_PATH, + _FREEDESKTOP_INTERFACE, "GetConnectionUnixProcessID", + g_variant_new ("(s)", sender), ((const GVariantType *) "(u)"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (response == NULL) { + _ERR("Failed to get caller id [%s]", error->message); + g_error_free (error); + return NULL; + } + + g_variant_get (response, "(u)", &upid); + _INFO("Remote msg-bus peer service=%s pid=%u", sender, upid); + //remote_pid = (pid_t) upid; + + g_variant_unref (response); + + char buf[128]; + int ret = 0; + + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", upid); + ret = __read_proc(buf, buf, sizeof(buf)); + if (ret <= 0) { + _ERR("No proc directory (%d)\n", upid); + return NULL; + } + + _INFO("Caller=[%s]", buf); + + return strdup(buf); +} + +gboolean +_auth_ui_selector_on_ui_response(Fido *object, GDBusMethodInvocation *invocation, int error, const char *ui_resp) +{ + _INFO(""); + + char *caller = __get_proc_path_of_dbus_caller(invocation); + if (caller == NULL) { + _ERR("__get_proc_path_of_dbus_caller failed"); + __start_ui_svc_term_timer(); + return true; + } + + if (strcmp(caller, _UI_SVC_BIN_PATH) != 0) { + _ERR("[%s] is not allowed", caller); + __start_ui_svc_term_timer(); + return true; + } + + _ui_response_cb_data_t *cb_data = (_ui_response_cb_data_t*)(g_queue_pop_head(_ui_q)); + if (cb_data == NULL) { + _ERR("Can not proceed since callback data is NULL"); + goto CATCH; + } + + if (cb_data->cb == NULL) { + _ERR("Can not proceed since callback data's cb part is NULL"); + goto CATCH; + } + + if (error != FIDO_ERROR_NONE) + cb_data->cb(error, NULL, cb_data->user_data); + else { + if (ui_resp == NULL) + cb_data->cb(FIDO_ERROR_PERMISSION_DENIED, NULL, cb_data->user_data); + else { + _INFO("response from server = [%s]", ui_resp); + + _ui_auth_data_t *ui_auth_data = _compose_json_ui_out(ui_resp); + cb_data->cb(FIDO_ERROR_NONE, ui_auth_data, cb_data->user_data); + } + } + +CATCH: + + if (g_queue_is_empty(_ui_q) == false) + _process_ui_selection_queue(); + else { + g_queue_free(_ui_q); + _ui_q = NULL; + __start_ui_svc_term_timer(); + } + + return true; +} diff --git a/server/fido_selection_ui_adaptor.h b/server/fido_selection_ui_adaptor.h new file mode 100644 index 0000000..f2ee329 --- /dev/null +++ b/server/fido_selection_ui_adaptor.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef FIDO_SELECTION_UI_ADAPTOR_H +#define FIDO_SELECTION_UI_ADAPTOR_H + +#include +#include +#include "fido-stub.h" +#include "fido_internal_types.h" + +gboolean _auth_ui_selector_on_ui_response(Fido *object, GDBusMethodInvocation *invocation, int error, const char *ui_resp); + +typedef void (*_ui_response_cb) (int eror_code, _ui_auth_data_t *selected_auth_data, void *user_data); +int _auth_ui_selector_send(GList *auth_list, _ui_response_cb cb, void *user_data); + +#endif // FIDO_SELECTION_UI_ADAPTOR_H diff --git a/server/fido_server.c b/server/fido_server.c new file mode 100755 index 0000000..297e3e6 --- /dev/null +++ b/server/fido_server.c @@ -0,0 +1,1378 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#if !GLIB_CHECK_VERSION (2, 31, 0) +#include +#endif + +#include "fido_privilege_checker.h" +#include "fido_asm_plugin_manager.h" +#include "fido_internal_types.h" +#include "fido_json_handler.h" +#include "fido_keys.h" +#include "fido_app_id_handler.h" +#include "fido_uaf_policy_checker.h" +#include "fido_selection_ui_adaptor.h" +#include "fido_logs.h" +#include "fido_uaf_types.h" +#include "fido-stub.h" + +#define _FIDO_SERVICE_DBUS_PATH "/org/tizen/fido" +static guint owner_id = 0; +//GDBusObjectManagerServer *fido_dbus_mgr = NULL; +static Fido* fido_dbus_obj = NULL; + +//TODO : current assumption is, ASM will handle multiple request queueing + +typedef struct _dbus_info{ + Fido *dbus_obj; + GDBusMethodInvocation *invocation; +}_dbus_info_t; + +typedef struct _discover_cb { + //fido_authenticator_cb cb; + void *user_data; + _dbus_info_t *dbus_info; +} discover_cb_t; + +typedef struct _fido_discover_asm_cb_data { + _fido_discover_asm_cb cb; + void *user_data; +}_fido_discover_asm_cb_data_t; + +typedef enum { + _PROCESS_TYPE_MIN = 0, + _PROCESS_TYPE_AUTH, + _PROCESS_TYPE_REG, + _PROCESS_TYPE_DEREG, + _PROCESS_TYPE_CHECK_POLICY, + _PROCESS_TYPE_MAX +} _process_type_t; + +typedef struct _process_cb_data { + _process_type_t type; + _message_t *uaf_req; + void *asm_in;/* ASM input data, type varies depending on operation name */ + _dbus_info_t *dbus_info; +} _process_cb_data_t; + +static void __process_dereg_queue(_dereg_q_t *dereg_q); + +static char** +__create_empty_json_2d_array(void) +{ + char **asm_resp_json_arr = calloc(1, sizeof(int)); + + char *empty_asm_resp = calloc(1, 128); + snprintf(empty_asm_resp, 127, "%s", _EMPTY_JSON_STRING); + asm_resp_json_arr[0] = empty_asm_resp; + + return asm_resp_json_arr; +} + +static void +__free_2d_string_array(char **arr, int row_count) +{ + RET_IF_FAIL_VOID(arr != NULL); + + int i = 0; + for (; i < row_count; i++) + SAFE_DELETE(arr[i]); + + SAFE_DELETE(arr); +} + +static char* +__dup_string(const char *source) +{ + if (source != NULL) + return strdup(source); + + return NULL; +} + +static void +__free_asm_discover_response_list_item(gpointer data) +{ + RET_IF_FAIL_VOID(data != NULL); + + _free_asm_discover_response((_asm_discover_response_t*)data); +} + +static void +__send_discover_response(Fido *object, GDBusMethodInvocation *invocation, int err, char **asm_resp_2d_arr, int asm_resp_len) +{ + if (asm_resp_2d_arr == NULL + || asm_resp_len <= 0) { + + char **empty_arr = __create_empty_json_2d_array(); + fido_complete_fido_uaf_discover(object, invocation, err, + (const gchar * const*)empty_arr, 0); + + __free_2d_string_array(empty_arr, 1); + return; + } + + fido_complete_fido_uaf_discover(object, invocation, err, + (const gchar * const*)asm_resp_2d_arr, asm_resp_len); + + __free_2d_string_array(asm_resp_2d_arr, asm_resp_len); +} + +void +_asm_get_info_cb(GList *asm_resp_list, void *user_data) +{ + _INFO("_asm_get_info_cb"); + + _dbus_info_t *dbus_info = (_dbus_info_t *)user_data; + if (dbus_info != NULL) { + + if (asm_resp_list != NULL) { + + int str_list_len = g_list_length(asm_resp_list); + char **asm_resp_json_arr = calloc(str_list_len, sizeof(int)); + int data_len = 0; + int i = 0; + + GList *asm_resp_list_iter = g_list_first(asm_resp_list); + while (asm_resp_list_iter != NULL) { + _asm_discover_response_t *disc_resp = (_asm_discover_response_t*)(asm_resp_list_iter->data); + + if (disc_resp->asm_response_json != NULL) { + asm_resp_json_arr[i++] = strdup(disc_resp->asm_response_json); + data_len++; + } + asm_resp_list_iter = g_list_next(asm_resp_list_iter); + } + + __send_discover_response(dbus_info->dbus_obj, dbus_info->invocation, FIDO_ERROR_NONE, + asm_resp_json_arr, data_len); + } + else + __send_discover_response(dbus_info->dbus_obj, dbus_info->invocation, FIDO_ERROR_NOT_SUPPORTED, + NULL, 0); + } + + if (asm_resp_list != NULL) + g_list_free_full(asm_resp_list, __free_asm_discover_response_list_item); +} + +static void +_send_process_response(_process_cb_data_t *cb_data, int tz_err_code, char *uaf_response_json) +{ + _INFO("_send_process_response"); + + /*TODO*/ + _dbus_info_t *dbus_info = (_dbus_info_t *)(cb_data->dbus_info); + if (dbus_info != NULL) + { + if (cb_data->type == _PROCESS_TYPE_CHECK_POLICY) { + _INFO("before fido_complete_fido_uaf_check_policy"); + fido_complete_fido_uaf_check_policy(dbus_info->dbus_obj, dbus_info->invocation, tz_err_code); + goto CATCH; + } + + _INFO("before fido_complete_fido_uaf_process_operation"); + + if (uaf_response_json != NULL) + fido_complete_fido_uaf_process_operation(dbus_info->dbus_obj, dbus_info->invocation, FIDO_ERROR_NONE, + uaf_response_json); + else + fido_complete_fido_uaf_process_operation(dbus_info->dbus_obj, dbus_info->invocation, tz_err_code, _EMPTY_JSON_STRING); + } + +CATCH: + SAFE_DELETE(uaf_response_json); + _free_message(cb_data->uaf_req); + + SAFE_DELETE(cb_data->dbus_info); + + if (cb_data->type == _PROCESS_TYPE_AUTH) + _free_fido_asm_auth_in((_fido_asm_auth_in_t*)(cb_data->asm_in)); + else if (cb_data->type == _PROCESS_TYPE_REG) + _free_fido_asm_reg_in((_fido_asm_reg_in_t*)(cb_data->asm_in)); + else if (cb_data->type == _PROCESS_TYPE_DEREG) + _free_fido_asm_dereg_in((_fido_asm_dereg_in_t*)(cb_data->asm_in)); + else + SAFE_DELETE(cb_data->asm_in); + + SAFE_DELETE(cb_data); +} + +void +_discover_response_intermediate_cb(GList *asm_response_list, void *user_data) +{ + _INFO("_discover_response_intermediate_cb"); + + _fido_discover_asm_cb_data_t *cb_data = (_fido_discover_asm_cb_data_t *)user_data; + + int error = FIDO_ERROR_NONE; + GList *asm_auth_list = NULL; + + if (asm_response_list == NULL) + _ERR("Discover response failed"); + else { + asm_auth_list = _uaf_parser_parse_asm_response_discover(asm_response_list, &error); + } + + (cb_data->cb)(error, 0, asm_auth_list, cb_data->user_data); + + if (asm_response_list != NULL) + g_list_free_full(asm_response_list, __free_asm_discover_response_list_item); +} + +static int +__fido_uaf_discover_internal(_fido_discover_asm_cb callback, void *user_data) +{ + _INFO("__fido_uaf_discover_internal"); + + _fido_discover_asm_cb_data_t *cb_data_inter_mediate = (_fido_discover_asm_cb_data_t *) calloc(1, sizeof(_fido_discover_asm_cb_data_t)); + cb_data_inter_mediate->cb = callback; + cb_data_inter_mediate->user_data = user_data; + + return _asm_plugin_mgr_discover_all(_discover_response_intermediate_cb, cb_data_inter_mediate); +} + +static void +_asm_response_auth_process(int error_code, const char *asm_response_json, void *user_data) +{ + _INFO("_asm_response_auth_process"); + + if (user_data == NULL) + _ERR("user_data is NULL"); + + _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data; + if (cb_data == NULL) { + _ERR("_process_cb_data_t not found"); + return; + } + + _INFO("error_code = [%d]", error_code); + + if (error_code != 0) { + _ERR("ASM response contains error code [%d]", error_code); + _send_process_response((_process_cb_data_t *)user_data, error_code, NULL); + return; + } + + _asm_out_t *asm_out = NULL; + + _INFO("before _uaf_parser_parse_asm_response_auth"); + + int parser_err = 0; + asm_out = _uaf_parser_parse_asm_response_auth(asm_response_json, &parser_err); + if (parser_err != 0 || asm_out == NULL) { + _ERR("_uaf_parser_parse_asm_response_auth failed"); + + int uaf_err_code = _convert_asm_status_code_to_uaf_error(parser_err); + if (uaf_err_code == FIDO_ERROR_NONE) + _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL); + else + _send_process_response(cb_data, uaf_err_code, NULL); + + _free_asm_out(asm_out); + asm_out = NULL; + + return; + } + + _asm_auth_out_t *asm_auth_out = (_asm_auth_out_t*)(asm_out->response_data); + + _fido_asm_auth_in_t *asm_auth_in = (_fido_asm_auth_in_t *) cb_data->asm_in; + + _message_t *uaf_message = cb_data->uaf_req; + + _op_header_t *header = uaf_message->header; + + char *uaf_response_json = NULL; + + + /* TODO : Add logic to accumulate multiple auth response and form the assertion_list*/ + GList *assertion_list = NULL; + + _auth_reg_assertion_t *asst_data = (_auth_reg_assertion_t*)calloc(1, sizeof(_auth_reg_assertion_t)); + + _INFO("before assertion"); + asst_data->assertion = strdup(asm_auth_out->assertion); + + _INFO("before assertion_schm"); + asst_data->assertion_schm = strdup(asm_auth_out->assertion_scheme); + + assertion_list = g_list_append(assertion_list, asst_data); + + assertion_list = g_list_first(assertion_list); + + + _INFO("before _uaf_composer_compose_uaf_process_response_auth"); + parser_err = _uaf_composer_compose_uaf_process_response_auth(header, asm_auth_in->final_challenge, + assertion_list, &uaf_response_json); + + g_list_free_full(assertion_list, _free_auth_reg_assertion_list_item); + + _free_asm_out(asm_out); + asm_out = NULL; + + if (parser_err != 0) { + _ERR("_uaf_composer_compose_uaf_process_response_auth failed"); + _send_process_response((_process_cb_data_t *)user_data, FIDO_ERROR_INVALID_PARAMETER, NULL); + return; + } + + _send_process_response(cb_data, FIDO_ERROR_NONE, uaf_response_json); +} + +static void +_asm_response_reg_process(int error_code, const char *asm_response_json, void *user_data) +{ + _INFO("_asm_response_reg_process"); + + _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data; + if (cb_data == NULL) + return; + + if (error_code != 0) { + _ERR("ASM response contains error code [%d]", error_code); + + _send_process_response((_process_cb_data_t *)user_data, error_code, NULL); + + return; + } + + _asm_out_t *asm_out = NULL; + int parser_err = 0; + asm_out = _uaf_parser_parse_asm_response_reg(asm_response_json, &parser_err); + if (parser_err != 0 || asm_out == NULL) { + _ERR("_uaf_parser_parse_asm_response_reg failed"); + + int uaf_err_code = _convert_asm_status_code_to_uaf_error(parser_err); + if (uaf_err_code == FIDO_ERROR_NONE) + _send_process_response((_process_cb_data_t *)user_data, FIDO_ERROR_PROTOCOL_ERROR, NULL); + else + _send_process_response((_process_cb_data_t *)user_data, uaf_err_code, NULL); + + _free_asm_out(asm_out); + + return; + } + + _asm_reg_out_t *asm_reg_out = (_asm_reg_out_t*)(asm_out->response_data); + + _fido_asm_reg_in_t *asm_reg_in = (_fido_asm_reg_in_t *)(cb_data->asm_in); + + _message_t *uaf_req = cb_data->uaf_req; + _op_header_t *header = uaf_req->header; + + char *uaf_response_json = NULL; + + /* TODO : Add logic to accumulate multiple auth response and form the assertion_list*/ + _auth_reg_assertion_t *ass_data = (_auth_reg_assertion_t*) calloc(1, sizeof(_auth_reg_assertion_t)); + ass_data->assertion = __dup_string(asm_reg_out->assertion); + ass_data->assertion_schm = __dup_string(asm_reg_out->assertion_schm); + + + _free_asm_out(asm_out); + asm_out = NULL; + + GList *ass_list = NULL; + ass_list = g_list_append(ass_list, ass_data); + + parser_err = _uaf_composer_compose_uaf_process_response_reg(header, asm_reg_in->final_challenge, + ass_list, &uaf_response_json); + + g_list_free_full(ass_list, _free_auth_reg_assertion_list_item); + + if (parser_err != 0) { + _ERR("_uaf_composer_compose_uaf_process_response_reg failed"); + _send_process_response((_process_cb_data_t *)user_data, FIDO_ERROR_INVALID_PARAMETER, NULL); + return; + } + + _send_process_response((_process_cb_data_t *)user_data, FIDO_ERROR_NONE, uaf_response_json); +} + +static void +__handle_reg(_process_cb_data_t *cb_data, _matched_auth_data_t *matched_auth) +{ + _INFO(""); + + _message_t *uaf_req = (_message_t *)(cb_data->uaf_req); + + _reg_request_t *uaf_reg_req = (_reg_request_t *)(cb_data->uaf_req->data); + + _fido_asm_reg_in_t *reg_in = (_fido_asm_reg_in_t*) calloc(1, sizeof(_fido_asm_reg_in_t)); + + /*If no app-id mentioned in UAF request*/ + if (cb_data->uaf_req->header->app_id == NULL) { + if (cb_data->uaf_req->facet_id == NULL) { + _ERR("Failed to get app id"); + _send_process_response(cb_data, FIDO_ERROR_UNTRUSTED_FACET_ID, NULL); + _free_fido_asm_reg_in(reg_in); + return; + } + /* app id*/ + cb_data->uaf_req->header->app_id = strdup(cb_data->uaf_req->facet_id); + reg_in->app_id = strdup(cb_data->uaf_req->header->app_id); + } + else { + /* app id*/ + reg_in->app_id = strdup(cb_data->uaf_req->header->app_id); + } + + /* user name */ + if (uaf_reg_req->user_name != NULL) + reg_in->user_name = strdup(uaf_reg_req->user_name); + + _INFO(""); + + char *fc_json = _uaf_composer_compose_final_challenge(reg_in->app_id, uaf_reg_req->challenge, + uaf_req->facet_id, cb_data->uaf_req->channel_binding); + + if (fc_json == NULL) { + _ERR("Failed to compose final challenge"); + _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL); + _free_fido_asm_reg_in(reg_in); + return; + } + + _INFO(""); + /* Final challenge */ + reg_in->final_challenge = fc_json; + + int auth_idx_int = -1; + sscanf(matched_auth->auth_index, "%d", &auth_idx_int); + + reg_in->attestation_type = matched_auth->att_type; + + _version_t *version = (_version_t *)calloc(1, sizeof(_version_t)); + version->major = _VERSION_MAJOR; + version->minor = _VERSION_MINOR; + + char *asm_req_json = NULL; + + cb_data->asm_in = reg_in; + + _INFO(""); + int ret = _uaf_composer_compose_asm_reg_request(version, auth_idx_int, reg_in, &asm_req_json); + if (ret == 0 && asm_req_json != NULL) + _asm_ipc_send(matched_auth->asm_id, + asm_req_json, _asm_response_reg_process, cb_data); + else + _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL); + + SAFE_DELETE(asm_req_json); + SAFE_DELETE(version); + +} + +static GList * +__copy_convert_uaf_trans_list(GList *uaf_tr_list) +{ + RET_IF_FAIL(uaf_tr_list != NULL, NULL); + + GList *asm_tr_list = NULL; + + GList *uaf_tr_list_iter = g_list_first(uaf_tr_list); + while (uaf_tr_list_iter != NULL) { + + _auth_transaction_t *uaf_tr = (_auth_transaction_t*)(uaf_tr_list_iter->data); + + _fido_asm_transaction_t *asm_tr = calloc(1, sizeof(_fido_asm_transaction_t)); + + asm_tr->content = __dup_string(uaf_tr->content); + asm_tr->content_type = __dup_string(uaf_tr->content_type); + if (uaf_tr->display_charac != NULL) { + asm_tr->display_charac = calloc(1, sizeof(_fido_asm_display_png_characteristics_descriptor_t)); + + asm_tr->display_charac->bit_depth = uaf_tr->display_charac->bit_depth; + asm_tr->display_charac->color_type = uaf_tr->display_charac->color_type; + asm_tr->display_charac->compression = uaf_tr->display_charac->compression; + asm_tr->display_charac->filter = uaf_tr->display_charac->filter; + asm_tr->display_charac->height = uaf_tr->display_charac->height; + asm_tr->display_charac->interlace = uaf_tr->display_charac->interlace; + asm_tr->display_charac->width = uaf_tr->display_charac->width; + + if (uaf_tr->display_charac->plte != NULL) { + + GList *uaf_plte_iter = g_list_first(uaf_tr->display_charac->plte); + while (uaf_plte_iter != NULL) { + fido_rgb_pallette_entry_s *uaf_plte_entry = (fido_rgb_pallette_entry_s*)(uaf_plte_iter->data); + + fido_rgb_pallette_entry_s *asm_plte_entry = calloc(1, sizeof(fido_rgb_pallette_entry_s)); + asm_plte_entry->r = uaf_plte_entry->r; + asm_plte_entry->g = uaf_plte_entry->g; + asm_plte_entry->b = uaf_plte_entry->b; + + asm_tr->display_charac->plte = g_list_append(asm_tr->display_charac->plte, asm_plte_entry); + + uaf_plte_iter = uaf_plte_iter->next; + } + } + } + + asm_tr_list = g_list_append(asm_tr_list, asm_tr); + + uaf_tr_list_iter = uaf_tr_list_iter->next; + } + + if (asm_tr_list != NULL) { + asm_tr_list = g_list_first(asm_tr_list); + _INFO("Trans list = [%d]", g_list_length(asm_tr_list)); + } + return asm_tr_list; +} + +static GList* +__copy_string_list(GList *src) +{ + _INFO(""); + + RET_IF_FAIL(src != NULL, NULL); + + GList *dest = NULL; + + GList *iter = g_list_first(src); + while (iter != NULL) { + char *str = (char*)(iter->data); + dest = g_list_append(dest, strdup(str)); + + iter = iter->next; + _INFO(""); + } + + _INFO(""); + return dest; +} + +static void +__handle_auth(_process_cb_data_t *cb_data, _matched_auth_data_t *matched_auth) +{ + _INFO("__handle_auth"); + + _auth_request_t *uaf_auth_req = (_auth_request_t*)(cb_data->uaf_req->data); + + _fido_asm_auth_in_t *auth_asm_in = (_fido_asm_auth_in_t*)calloc(1, sizeof(_fido_asm_auth_in_t)); + + if (cb_data->uaf_req->header->app_id == NULL) { + + if (cb_data->uaf_req->facet_id == NULL) { + _ERR("Failed to get app id"); + _send_process_response(cb_data, FIDO_ERROR_PERMISSION_DENIED, NULL); + _free_fido_asm_auth_in(auth_asm_in); + return; + } + cb_data->uaf_req->header->app_id = strdup(cb_data->uaf_req->facet_id); + auth_asm_in->app_id = strdup(cb_data->uaf_req->facet_id); + } + else { + auth_asm_in->app_id = strdup(cb_data->uaf_req->header->app_id); + } + + char *fc_json = _uaf_composer_compose_final_challenge(cb_data->uaf_req->header->app_id, + uaf_auth_req->challenge, cb_data->uaf_req->facet_id, + cb_data->uaf_req->channel_binding); + if (fc_json == NULL) { + _ERR("Failed to compose final challenge"); + _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL); + + _free_fido_asm_auth_in(auth_asm_in); + return; + } + + /*keyIDs*/ + auth_asm_in->key_ids = __copy_string_list(matched_auth->key_ids); + + /* Final challenge */ + auth_asm_in->final_challenge = fc_json; + + /*Transaction*/ + auth_asm_in->trans_list = __copy_convert_uaf_trans_list(uaf_auth_req->transaction_list); + + + cb_data->asm_in = auth_asm_in; + + char *asm_req_json = NULL; + _version_t *version = (_version_t *)calloc(1, sizeof(_version_t)); + version->major = _VERSION_MAJOR; + version->minor = _VERSION_MINOR; + + int auth_idx_int = -1; + sscanf(matched_auth->auth_index, "%d", &auth_idx_int); + if (auth_idx_int == -1) { + _ERR("ASM in data missing"); + _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL); + + _free_fido_asm_auth_in(auth_asm_in); + SAFE_DELETE(version); + + return; + } + + int ret = _uaf_composer_compose_asm_auth_request(version, auth_idx_int, auth_asm_in, &asm_req_json); + if (ret == 0 && asm_req_json != NULL) { + _asm_ipc_send(matched_auth->asm_id, + asm_req_json, _asm_response_auth_process, cb_data); + } + else { + _send_process_response(cb_data, FIDO_ERROR_INVALID_PARAMETER, NULL); + } + + SAFE_DELETE(version); + SAFE_DELETE(asm_req_json); +} + +static void +_ui_response_callback(int error_code, _ui_auth_data_t *selected_auth_data, void *user_data) +{ + if (selected_auth_data == NULL) { + _ERR("User did not select any Authenticator"); + _send_process_response((_process_cb_data_t *)user_data, error_code, NULL); + free(selected_auth_data); + return; + } + + _INFO("User selected [%s] authenticator index", selected_auth_data->auth_index); + + _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data; + + + _matched_auth_data_t *match_data = (_matched_auth_data_t*)calloc(1, sizeof(_matched_auth_data_t)); + match_data->att_type = selected_auth_data->att_type; + match_data->auth_index = selected_auth_data->auth_index; + match_data->asm_id = strdup(selected_auth_data->asm_id); + + if (cb_data->type == _PROCESS_TYPE_REG) + __handle_reg(cb_data, match_data); + + if (cb_data->type == _PROCESS_TYPE_AUTH) + __handle_auth(cb_data, match_data); + + _free_matched_auth_data(match_data); + +} + +static void +_asm_response_dereg_process(int error_code, const char *asm_response_json, void *user_data) +{ + _dereg_q_t *dereg_q = (_dereg_q_t*)(user_data); + _process_cb_data_t *cb_data = (_process_cb_data_t*)(dereg_q->cb_data); + + if (cb_data == NULL) + return; + + /*Process next dereg*/ + GQueue *q = (GQueue*) (dereg_q->dereg_asm_in_q); + if (g_queue_is_empty(q) == FALSE) + __process_dereg_queue(user_data); + else { + /*ASM does not return success/faliure for dereg*/ + _INFO("Ignoring ASM's response for dereg"); + _send_process_response((_process_cb_data_t *)cb_data, FIDO_ERROR_NONE, NULL); + + _INFO("Deleting dereg_asm_in_q"); + /*Elements were deleted during pop*/ + g_queue_free(dereg_q->dereg_asm_in_q); + dereg_q->dereg_asm_in_q = NULL; + _INFO("After Deleting dereg_asm_in_q"); + } + +} + +static void +__process_dereg_queue(_dereg_q_t *dereg_q) +{ + _INFO("__process_dereg_queue"); + + GQueue *q = dereg_q->dereg_asm_in_q; + if (q == NULL) + return; + + if (g_queue_is_empty(q) == true) { + _INFO("Deleting dereg_asm_in_q"); + g_queue_free(dereg_q->dereg_asm_in_q); + dereg_q->dereg_asm_in_q = NULL; + _INFO("After Deleting dereg_asm_in_q"); + return; + } + + _process_cb_data_t *cb_data = (_process_cb_data_t*)(dereg_q->cb_data); + _message_t *uaf_message = cb_data->uaf_req; + + _matched_auth_dereg_t *dereg_data = (_matched_auth_dereg_t*)(g_queue_pop_head(q)); + + char *asm_req_json = NULL; + + int auth_index_int = _INVALID_INT; + sscanf(dereg_data->auth_index, "%d", &auth_index_int); + + _INFO("Auth index for dereg req = [%d]", auth_index_int); + + int ret = _uaf_composer_compose_asm_dereg_request(uaf_message->header->version, auth_index_int, + dereg_data, &asm_req_json); + + /*TODO : ASM does not return anything for dereg, so do not wait for response, send back + * success always. + */ + if (ret == 0 && asm_req_json != NULL) { + _asm_ipc_send(dereg_data->asm_id, + asm_req_json, _asm_response_dereg_process, dereg_q); + } + else { + _send_process_response(cb_data, FIDO_ERROR_INVALID_PARAMETER, NULL); + } + + _free_matched_auth_dereg(dereg_data); + SAFE_DELETE(asm_req_json); + +} + +static GList* +__get_keyid_list_from_app_reg(GList *app_reg_list) +{ + _INFO("__get_keyid_list_from_app_reg"); + + RET_IF_FAIL(app_reg_list != NULL, NULL); + + GList *key_id_list = NULL; + + GList *app_reg_list_iter = g_list_first(app_reg_list); + while (app_reg_list_iter != NULL) { + + _asm_app_reg_t *app_reg = (_asm_app_reg_t*)(app_reg_list_iter->data); + if (app_reg != NULL) { + + if (app_reg->key_id_list != NULL) { + GList *key_id_list_iter = g_list_first(app_reg->key_id_list); + while (key_id_list_iter != NULL) { + char *key_id = (char*)(key_id_list_iter->data); + if (key_id != NULL) { + key_id_list = g_list_append(key_id_list, strdup(key_id)); + _INFO("[%s]", key_id); + } + + key_id_list_iter = key_id_list_iter->next; + } + } + } + + app_reg_list_iter = app_reg_list_iter->next; + } + + return key_id_list; +} + +static GList * +__get_auth_list_with_keyids(GList *available_authenticators) +{ + _INFO("__get_auth_list_with_keyids"); + + GList *available_authenticators_full = NULL; + + GList *avl_auth_iter = g_list_first(available_authenticators); + while (avl_auth_iter != NULL) { + + fido_authenticator_s *asm_auth = (fido_authenticator_s*)(avl_auth_iter->data); + if (asm_auth != NULL) { + char *get_reg_json = _uaf_composer_compose_get_registrations_request(asm_auth->auth_index); + char *get_reg_resp = _asm_ipc_send_sync(asm_auth->asm_id, get_reg_json); + + if (get_reg_resp != NULL) + _INFO("_asm_ipc_send_sync = [%s]", get_reg_resp); + + _asm_get_reg_out_t *get_reg_out = _uaf_parser_parser_asm_get_reg_response(get_reg_resp); + if (get_reg_out != NULL) { + asm_auth->key_ids = __get_keyid_list_from_app_reg(get_reg_out->app_reg_list); + asm_auth->key_ids = g_list_first(asm_auth->key_ids); + _INFO(" asm_auth->key_ids count = [%d]", g_list_length(asm_auth->key_ids)); + } + available_authenticators_full = g_list_append(available_authenticators_full, asm_auth); + + SAFE_DELETE(get_reg_json); + SAFE_DELETE(get_reg_resp); + _free_asm_get_reg_out(get_reg_out); + + } + avl_auth_iter = avl_auth_iter->next; + } + + return available_authenticators_full; +} + +static void +__free_matched_dereg_auth_data_list_item(gpointer data) +{ + RET_IF_FAIL_VOID(data != NULL); + + _free_matched_auth_dereg((_matched_auth_dereg_t*)data); +} + +static void +_discover_response_cb_for_process(int tz_error_code, int error_code, GList *available_authenticators, void *user_data) +{ + _INFO("_discover_response_cb_for_process [%p]", user_data); + + _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data; + + if (tz_error_code != FIDO_ERROR_NONE) { + _ERR("Failed to get available authenticator info [%d]", tz_error_code); + _send_process_response(cb_data, FIDO_ERROR_NOT_SUPPORTED, NULL); + return; + } + + if (available_authenticators == NULL) { + _ERR("No supported authenticators found"); + _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL); + return; + } + + _INFO("cb_data->type = [%d]", cb_data->type); + + GList *available_authenticators_full = g_list_first(available_authenticators); + + if (cb_data->type == _PROCESS_TYPE_CHECK_POLICY) { + + _INFO("_PROCESS_TYPE_CHECK_POLICY"); + + if (cb_data->uaf_req->header->operation != NULL) + _INFO("operation = [%s]", cb_data->uaf_req->header->operation); + else + _ERR("operation = [NULL]"); + + if ((strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_REG) == 0) + || ((strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_AUTH) == 0))) { + + _policy_t *policy = NULL; + + if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_REG) == 0) { + _reg_request_t *uaf_reg_req = (_reg_request_t *)(cb_data->uaf_req->data); + policy = uaf_reg_req->policy; + _INFO("_PROCESS_TYPE_CHECK_POLICY for reg"); + } + else if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_AUTH) == 0) { + _auth_request_t *uaf_auth_req = (_auth_request_t *)(cb_data->uaf_req->data); + policy = uaf_auth_req->policy; + _INFO("_PROCESS_TYPE_CHECK_POLICY for auth"); + } + + if (policy->is_keyid_present == true) { + /*Available authenticators' keyIDs can be fetched via GetRegistrations ASM op*/ + _INFO("Need to call GetRegistrations to match policy"); + GList *avl_auth_list_full_temp = __get_auth_list_with_keyids(available_authenticators); + if (avl_auth_list_full_temp != NULL) { + g_list_free(available_authenticators_full); + + available_authenticators_full = g_list_first(avl_auth_list_full_temp); + } + + } + GList *allowed_auth_list = _policy_checker_get_matched_auth_list(policy, available_authenticators_full); + g_list_free_full(available_authenticators_full, _free_asm_auth_list); + + if ((allowed_auth_list != NULL) && g_list_length(allowed_auth_list) > 0) { + + _send_process_response(cb_data, FIDO_ERROR_NONE, NULL); + } + else { + _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL); + } + + if (allowed_auth_list != NULL) + g_list_free_full(allowed_auth_list, _free_matched_auth_data); + + } + else if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_DE_REG) == 0) { + + _dereg_request_t *dereg_req = (_dereg_request_t*)(cb_data->uaf_req->data); + + /* _matched_auth_dereg_t list*/ + if (cb_data->uaf_req->header->app_id == NULL) + cb_data->uaf_req->header->app_id = strdup(cb_data->uaf_req->facet_id); + + GList *matched_auth_list = _policy_checker_get_matched_auth_list_dereg(cb_data->uaf_req->header->app_id, dereg_req->auth_info_list, + available_authenticators_full); + g_list_free_full(available_authenticators_full, _free_asm_auth_list); + + if ((matched_auth_list != NULL) && g_list_length(matched_auth_list) > 0) { + + _send_process_response(cb_data, FIDO_ERROR_NONE, NULL); + } + else { + _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL); + } + + if (matched_auth_list != NULL) + g_list_free_full(matched_auth_list, __free_matched_dereg_auth_data_list_item); + + } + + return; + } + if (cb_data->type == _PROCESS_TYPE_DEREG) { + + + _dereg_request_t *dereg_req = (_dereg_request_t*)(cb_data->uaf_req->data); + + if (cb_data->uaf_req->header->app_id == NULL) + cb_data->uaf_req->header->app_id = strdup(cb_data->uaf_req->facet_id); + + /* _matched_auth_dereg_t list*/ + GList *matched_auth_list = _policy_checker_get_matched_auth_list_dereg(cb_data->uaf_req->header->app_id, dereg_req->auth_info_list, + available_authenticators_full); + + g_list_free_full(available_authenticators_full, _free_asm_auth_list); + + if (matched_auth_list == NULL){ + _ERR("No supported authenticators found"); + _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL); + return; + } + + _dereg_q_t *dereg_q = (_dereg_q_t*) calloc(1, sizeof(_dereg_q_t)); + + GList *matched_auth_list_iter = g_list_first(matched_auth_list); + while (matched_auth_list_iter != NULL) { + _matched_auth_dereg_t *dereg_auth_matched = (_matched_auth_dereg_t*) (matched_auth_list_iter->data); + + if (dereg_auth_matched != NULL) { + GQueue *q = dereg_q->dereg_asm_in_q; + + if (q == NULL) + dereg_q->dereg_asm_in_q = g_queue_new(); + + g_queue_push_head(dereg_q->dereg_asm_in_q, dereg_auth_matched); + } + matched_auth_list_iter = matched_auth_list_iter->next; + } + + /*The elements will be deleted while freeing dereg_q->dereg_asm_in_q*/ + g_list_free(matched_auth_list); + + dereg_q->cb_data = cb_data; + + __process_dereg_queue(dereg_q); + + return; + } + + _policy_t *policy = NULL; + + if (cb_data->type == _PROCESS_TYPE_REG) { + _reg_request_t *uaf_reg_req = (_reg_request_t *)(cb_data->uaf_req->data); + policy = uaf_reg_req->policy; + } + else if (cb_data->type == _PROCESS_TYPE_AUTH) { + _auth_request_t *uaf_auth_req = (_auth_request_t *)(cb_data->uaf_req->data); + policy = uaf_auth_req->policy; + } + else { + _send_process_response(cb_data, FIDO_ERROR_UNKNOWN, NULL); + return; + } + + if (policy->is_keyid_present == true) { + /*Available authenticators' keyIDs can be fetched via GetRegistrations ASM op*/ + _INFO("Need to call GetRegistrations to match policy"); + GList *avl_auth_list_full_temp = __get_auth_list_with_keyids(available_authenticators); + if (avl_auth_list_full_temp != NULL) { + g_list_free(available_authenticators_full); + available_authenticators_full = g_list_first(avl_auth_list_full_temp); + } + + } + + GList *allowed_auth_list = _policy_checker_get_matched_auth_list(policy, available_authenticators_full); + g_list_free_full(available_authenticators_full, _free_asm_auth_list); + + if (allowed_auth_list == NULL){ + _ERR("No supported authenticators found"); + _send_process_response(cb_data, FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR, NULL); + + return; + } + + _INFO(""); + allowed_auth_list = g_list_first(allowed_auth_list); + + if (g_list_length(allowed_auth_list) > 1) { + _INFO(""); + + GList *ui_data_list = NULL; + + GList *allowed_auth_list_iter = allowed_auth_list; + while (allowed_auth_list_iter != NULL) { + _matched_auth_data_t *match_data = (_matched_auth_data_t *)(allowed_auth_list_iter->data); + + if (match_data != NULL) { + + _ui_auth_data_t *ui_data = (_ui_auth_data_t*) calloc(1, sizeof(_ui_auth_data_t)); + if (match_data->asm_id != NULL) + ui_data->asm_id = strdup(match_data->asm_id); + else + _ERR("No ASM id found to send to UI!!"); + + ui_data->auth_index = strdup(match_data->auth_index); + ui_data->att_type = match_data->att_type; + + ui_data->label = strdup(match_data->label); + + ui_data_list = g_list_append(ui_data_list, ui_data); + + allowed_auth_list_iter = allowed_auth_list_iter->next; + } + } + + int ret = _auth_ui_selector_send(ui_data_list, _ui_response_callback, cb_data); + if (ret != 0) { + _ERR("Failed to invoke selector UI"); + _send_process_response(cb_data, FIDO_ERROR_NOT_SUPPORTED, NULL); + if (allowed_auth_list != NULL) + g_list_free_full(allowed_auth_list, _free_matched_auth_data); + return; + } + } + else { + _INFO(""); + GList *allowed_auth_list_iter = allowed_auth_list; + _matched_auth_data_t *match_data = (_matched_auth_data_t *)(allowed_auth_list_iter->data); + + if (cb_data->type == _PROCESS_TYPE_REG) + __handle_reg(cb_data, match_data); + + else if (cb_data->type == _PROCESS_TYPE_AUTH) + __handle_auth(cb_data, match_data); + + } + if (allowed_auth_list != NULL) + g_list_free_full(allowed_auth_list, _free_matched_auth_data); + +} + +static int +_handle_process_message(_process_cb_data_t *cb_data) +{ + return __fido_uaf_discover_internal(_discover_response_cb_for_process, cb_data); +} + +static void +__facet_id_cb(int err, const char *facet_id, void *user_data) +{ + _INFO("__facet_id_cb"); + if (facet_id != NULL) + _INFO("[%s]", facet_id); + + _process_cb_data_t *cb_data = (_process_cb_data_t*)user_data; + + if (err != FIDO_ERROR_NONE || facet_id == NULL) { + _send_process_response(cb_data, err, NULL); + return; + } + + cb_data->uaf_req->facet_id = strdup(facet_id); + + int error_code = FIDO_ERROR_NONE; + + if (cb_data->type != _PROCESS_TYPE_CHECK_POLICY) { + + /** + * 1. Extract embedded policy to find the suitable authenticator(s) + * 2. Show UI to let user select one, if (1) gives multiple result. + * 3. Compose ASMRequest in json format + * 4. Send the same to asm + * 5. Send the ASMResponse to application. + */ + + if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_REG) == 0) + cb_data->type = _PROCESS_TYPE_REG; + + else if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_AUTH) == 0) + cb_data->type = _PROCESS_TYPE_AUTH; + + else if (strcmp(cb_data->uaf_req->header->operation, _UAF_OPERATION_NAME_KEY_DE_REG) == 0) + cb_data->type = _PROCESS_TYPE_DEREG; + + else { + _send_process_response(cb_data, FIDO_ERROR_INVALID_PARAMETER, NULL); + return; + } + } + + error_code = _handle_process_message(cb_data); + + if (error_code != FIDO_ERROR_NONE) { + _send_process_response(cb_data, error_code, NULL); + } +} + +gboolean +_dbus_on_fido_init(Fido *object, GDBusMethodInvocation *invocation) +{ + fido_complete_fido_uaf_init(object, invocation, FIDO_ERROR_NONE); + + return true; +} + +gboolean +_dbus_on_fido_deinit(Fido *object, GDBusMethodInvocation *invocation) +{ + if (is_allowed_to_call(invocation, _FIDO_CLIENT_PRIVILEGE) == false) { + fido_complete_fido_uaf_deinit(object, invocation, FIDO_ERROR_PERMISSION_DENIED); + } + else { + //_auth_ui_selector_deinit(); + fido_complete_fido_uaf_deinit(object, invocation, FIDO_ERROR_NONE); + } + + return true; +} + +gboolean +_dbus_on_fido_discover(Fido *object, GDBusMethodInvocation *invocation) +{ + _INFO("_dbus_on_fido_discover"); + if (is_allowed_to_call(invocation, _FIDO_CLIENT_PRIVILEGE) == false) { + + __send_discover_response(object, invocation, FIDO_ERROR_PERMISSION_DENIED, + NULL, 0); + return true; + } + + _dbus_info_t *dbus_info = (_dbus_info_t *)calloc(1, sizeof(_dbus_info_t)); + dbus_info->dbus_obj = object; + dbus_info->invocation = invocation; + + int ret = _asm_plugin_mgr_discover_all(_asm_get_info_cb, dbus_info); + if (ret != FIDO_ERROR_NONE) { + + _ERR("_asm_ipc_send failed = [%d]", ret); + __send_discover_response(dbus_info->dbus_obj, dbus_info->invocation, FIDO_ERROR_NOT_SUPPORTED, + NULL, 0); + + SAFE_DELETE(dbus_info); + + } + + return true; +} + +gboolean +_dbus_handle_process_or_check_policy(Fido *object, GDBusMethodInvocation *invocation, + const gchar *uaf_request_json, const gchar *channel_binding, + _process_type_t type) +{ + + _INFO("_dbus_handle_process_or_check_policy"); + + _process_cb_data_t *cb_data = (_process_cb_data_t*) calloc(1, sizeof(_process_cb_data_t)); + _dbus_info_t *dbus_info = (_dbus_info_t *)calloc(1, sizeof(_dbus_info_t)); + dbus_info->dbus_obj = object; + dbus_info->invocation = invocation; + cb_data->dbus_info = dbus_info; + cb_data->type = type; + + if (is_allowed_to_call(invocation, _FIDO_CLIENT_PRIVILEGE) == false) { + _send_process_response(cb_data, FIDO_ERROR_PERMISSION_DENIED, NULL); + return true; + } + + if (uaf_request_json == NULL) { + _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL); + return true; + } + + _INFO("%s", uaf_request_json); + + _message_t *uaf_message = _uaf_parser_parse_message(uaf_request_json, channel_binding); + if (uaf_message == NULL) { + _send_process_response(cb_data, FIDO_ERROR_PROTOCOL_ERROR, NULL); + return true; + } + + + cb_data->uaf_req = uaf_message; + + + int ret = _verify_and_get_facet_id(uaf_message->header->app_id, invocation, __facet_id_cb, cb_data); + if (ret != FIDO_ERROR_NONE) { + _send_process_response(cb_data, FIDO_ERROR_UNTRUSTED_FACET_ID, NULL); + return true; + } + + return true; +} + +gboolean +_dbus_on_fido_uaf_is_supported(Fido *object, GDBusMethodInvocation *invocation, + const gchar *uaf_request_json) +{ + _INFO("_dbus_on_fido_uaf_is_supported"); + + return _dbus_handle_process_or_check_policy(object, invocation, uaf_request_json, NULL, + _PROCESS_TYPE_CHECK_POLICY); +} + +gboolean +_dbus_on_fido_process_operation(Fido *object, GDBusMethodInvocation *invocation, + const gchar *uaf_request_json, const gchar* channel_binding_json) +{ + _INFO("_dbus_on_fido_process_operation"); + + return _dbus_handle_process_or_check_policy(object, invocation, uaf_request_json, + channel_binding_json, _PROCESS_TYPE_MIN); +} + +/*gboolean +_dbus_on_fido_uaf_notify_result(Fido *object, GDBusMethodInvocation *invocation, const gchar *arg_cookie, gint arg_respose_code, + const gchar *uaf_response_json) +{ + fido_complete_fido_uaf_notify_result(object, invocation, 0, 0); + return true; +}*/ + +static void +on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + dlog_print(DLOG_INFO, "FIDO", "on_bus_acquired"); + + _INFO("on_bus_acquired [%s]", name); + + GDBusInterfaceSkeleton* interface = NULL; + fido_dbus_obj = fido_skeleton_new(); + if (fido_dbus_obj == NULL) { + _ERR("fido_dbus_obj NULL!!"); + return; + } + + dlog_print(DLOG_INFO, "FIDO", "G_DBUS_INTERFACE_SKELETON"); + + interface = G_DBUS_INTERFACE_SKELETON(fido_dbus_obj); + if (!g_dbus_interface_skeleton_export(interface, connection, _FIDO_SERVICE_DBUS_PATH, NULL)) { + _ERR("export failed!!"); + return; + } + + dlog_print(DLOG_INFO, "FIDO", "g_signal_connect"); + + _INFO("connecting fido signals start"); + + g_signal_connect(fido_dbus_obj, "handle_fido_uaf_init", + G_CALLBACK(_dbus_on_fido_init), NULL); + + g_signal_connect(fido_dbus_obj, "handle_fido_uaf_deinit", + G_CALLBACK(_dbus_on_fido_deinit), NULL); + + g_signal_connect(fido_dbus_obj, "handle_fido_uaf_discover", + G_CALLBACK(_dbus_on_fido_discover), NULL); + + g_signal_connect(fido_dbus_obj, "handle_fido_uaf_check_policy", + G_CALLBACK(_dbus_on_fido_uaf_is_supported), NULL); + + g_signal_connect(fido_dbus_obj, "handle_fido_uaf_process_operation", + G_CALLBACK(_dbus_on_fido_process_operation), NULL); + +// g_signal_connect(fido_dbus_obj, "handle_fido_uaf_notify_result", +// G_CALLBACK(_dbus_on_fido_uaf_notify_result), NULL); + + g_signal_connect(fido_dbus_obj, "handle_ui_response", + G_CALLBACK(_auth_ui_selector_on_ui_response), NULL); + + if (_asm_plugin_mgr_init() != FIDO_ERROR_NONE) { + _ERR("Falied to init ASM plugin manager"); + dlog_print(DLOG_INFO, "FIDO", "_asm_plugin_mgr_init failed"); + exit(1); + } + + +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + _INFO("on_name_acquired"); + +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + _INFO("on_name_lost"); + _asm_plugin_mgr_destroy(); + exit (1); +} + +static bool +__initialize_dbus(void) +{ + _INFO("__initialize_dbus Enter"); + + owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, + _FIDO_DBUS_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, + NULL); + + _INFO("owner_id=[%d]", owner_id); + + if(owner_id == 0) { + _INFO("gdbus own failed!!"); + return false; + } + + _INFO("g_bus_own_name SUCCESS"); + return true; +} + +static void +__initialize(void) +{ +#if !GLIB_CHECK_VERSION(2,35,0) + g_type_init(); +#endif + + if (__initialize_dbus() == false) { + _ERR("DBUS Initialization Failed"); + exit(1); + } +} + +int +main(void) +{ + GMainLoop *mainloop = NULL; + + dlog_print(DLOG_INFO, "FIDO", "start"); + + _INFO("Starting FIDO SVC"); + + mainloop = g_main_loop_new(NULL, FALSE); + + __initialize(); + + g_main_loop_run(mainloop); + + _INFO("Ending FIDO SVC"); + return 0; +} diff --git a/server/fido_uaf_policy_checker.c b/server/fido_uaf_policy_checker.c new file mode 100644 index 0000000..b077abe --- /dev/null +++ b/server/fido_uaf_policy_checker.c @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include "fido_keys.h" +#include "fido_logs.h" +#include "fido_uaf_policy_checker.h" +#include "fido_json_handler.h" + +//static _fido_asm_proxy_t* +//__dup_asm_proxy(const _fido_asm_proxy_t *src) +//{ +// _fido_asm_proxy_t *dest = calloc(1, sizeof(_fido_asm_proxy_t)); +// dest->bin_path = strdup(src->bin_path); +// dest->dbus_info = strdup(src->dbus_info); +// dest->dbus_interface_name = strdup(src->dbus_interface_name); +// dest->dbus_method_name = strdup(src->dbus_method_name); +// dest->dbus_obj_path = strdup(src->dbus_obj_path); +// dest->vendor = strdup(src->vendor); + +// dest->dbus_proxy = src->dbus_proxy; + +// return dest; +//} + +static gint +_int_cmp(gconstpointer a, gconstpointer b) +{ + int int1 = GPOINTER_TO_INT(a); + int int2 = GPOINTER_TO_INT(b); + return (int1 - int2); +} + +bool +_policy_checker_is_matched(_match_criteria_t *match_criteria, fido_authenticator_s *auth_info) +{ + _INFO("_policy_checker_is_matched"); + + /* -1 means the int value is not present, so we should ignore that. */ + + /* 1. If any AAID is mentioned in match_criteria, then atleast one AAID should match */ + GList *aaid_list = match_criteria->aaid_list; + + if (aaid_list && + (g_list_length(aaid_list)) && + (auth_info->aaid) && + (strlen(auth_info->aaid) > 0)) { + aaid_list = g_list_first(aaid_list); + if (g_list_find_custom(aaid_list, auth_info->aaid, (GCompareFunc)strcmp) == NULL) { + _ERR("AAID match failed"); + return false; + } + } + + + /* 2. If any Vendor ID is mentioned in match_criteria, then atleast one Vendor ID should match */ + GList *vendor_list = match_criteria->vendor_list; + + if (vendor_list && auth_info->aaid) { + char *auth_aaid = strdup(auth_info->aaid); + char *auth_vendor = strtok(auth_aaid, "#"); + + if (vendor_list && + (g_list_length(vendor_list)) && + auth_vendor && + (strlen(auth_vendor) > 0)) { + vendor_list = g_list_first(vendor_list); + if (g_list_find_custom(vendor_list, auth_vendor, (GCompareFunc)strcmp) == NULL) { + _ERR("Vendor ID match failed"); + + SAFE_DELETE(auth_aaid); + return false; + } + } + SAFE_DELETE(auth_aaid); + } + + _INFO("keyid matching"); + + /* 3. If any Key ID is mentioned in match_criteria, then atleast one Key ID should match */ + GList *key_id_list = match_criteria->key_id_list; + + if (key_id_list != NULL) { + + if (auth_info->key_ids == NULL) { + _ERR("keyID match failed"); + return false; + } + + GList *auth_key_ids = auth_info->key_ids; + + GList *common_key_id_list = NULL; + + key_id_list = g_list_first(key_id_list); + auth_key_ids = g_list_first(auth_key_ids); + + _INFO("match_criteria keyid count = [%d]", g_list_length(key_id_list)); + _INFO("auth info keyid count = [%d]", g_list_length(auth_key_ids)); + + GList *key_id_iter = g_list_first(key_id_list); + while (key_id_iter != NULL) { + char *key_id = (char*) (key_id_iter->data); + if (key_id) { + if (g_list_find_custom(auth_key_ids, key_id, (GCompareFunc)strcmp) != NULL) { + _INFO("keyid matched [%s]", key_id); + common_key_id_list = g_list_append(common_key_id_list, strdup(key_id)); + } + } + key_id_iter = key_id_iter->next; + } + + if (common_key_id_list == NULL) { + _ERR("keyID match failed"); + return false; + } + + common_key_id_list = g_list_first(common_key_id_list); + + /*Set common keyIds in match*/ + g_list_free_full(match_criteria->key_id_list, free); + match_criteria->key_id_list = common_key_id_list; + + _INFO("keyID matched count [%d]", g_list_length(match_criteria->key_id_list)); + + } + + _INFO("User verification matching"); + + /* 4. User verification match */ + if (match_criteria->user_verification != -1) { + if ((match_criteria->user_verification == auth_info->user_verification) + || + ( + ((auth_info->user_verification & _USER_VER_METHOD_ALL) == 0) + && + ((match_criteria->user_verification & _USER_VER_METHOD_ALL) == 0) + && + ((auth_info->user_verification & match_criteria->user_verification) != 0) + ) + ) + _INFO("User verification match passed"); + else { + _ERR("User verification match failed"); + return false; + } + } + + /* 5. Key protection field bit matching */ + if ((match_criteria->key_protection != -1) && auth_info->key_protection) { + if (((match_criteria->key_protection) && (auth_info->key_protection)) == 0) { + _ERR("Key protection match failed"); + return false; + } + } + + /* 6. Matcher Protection field bit matching */ + if ((match_criteria->matcher_protection != -1) && auth_info->matcher_protection) { + if (((match_criteria->matcher_protection) && (auth_info->matcher_protection)) == 0) { + _ERR("Matcher protection match failed"); + return false; + } + } + + /* 7. Attachment hint field bit matching */ + if ((match_criteria->attachement_hint != -1) && auth_info->attachment_hint) { + if (((match_criteria->attachement_hint) && (auth_info->attachment_hint)) == 0) { + _ERR("Attachment hint match failed"); + return false; + } + } + + /* 8. TC Display field bit matching */ + if ((match_criteria->tc_display != -1) && auth_info->tc_display) { + if (((match_criteria->tc_display) && (auth_info->tc_display)) == 0) { + _ERR("Attachment hint match failed"); + return false; + } + } + + /* 9. If any algo is mentioned in match_criteria, then atleast one algo should match */ + GList *match_algo_list = match_criteria->auth_algo_list; + if (match_algo_list && (g_list_length(match_algo_list)) + && (auth_info->authentication_algorithm)) { + match_algo_list = g_list_first(match_algo_list); + if (g_list_find_custom(match_algo_list, GINT_TO_POINTER(auth_info->authentication_algorithm), (GCompareFunc)_int_cmp) == NULL) { + _ERR("Algorithm match failed"); + return false; + } + } + + /* 10. If any assertion scheme is mentioned in match_criteria, then atleast one assertion scheme should match */ + GList *assertion_list = match_criteria->assertion_scheme_list; + if (assertion_list && (g_list_length(assertion_list)) + && (auth_info->assertion_scheme) && (strlen(auth_info->assertion_scheme) > 0)) { + assertion_list = g_list_first(assertion_list); + if (g_list_find_custom(assertion_list, auth_info->assertion_scheme, (GCompareFunc)strcmp) == NULL) + { + _ERR("Assertion scheme match failed"); + return false; + } + } + + /* 11. If any attestation type is mentioned in match_criteria, then atleast one attestation type should match */ + GList *attestation_type_list = match_criteria->attestation_type_list; + if (attestation_type_list && (g_list_length(attestation_type_list)) + && (auth_info->attestation_types)) { + attestation_type_list = g_list_first(attestation_type_list); + if (g_list_find_custom(attestation_type_list, GINT_TO_POINTER(auth_info->attestation_types), (GCompareFunc)_int_cmp) == NULL) { + _ERR("Attestation type match failed"); + return false; + } + } + + /* TODO : 12. Auth version */ + + /* TODO : 13. Extension */ + + _INFO("_policy_checker_is_matched true"); + + return true; +} + +int +_get_attestation_type(_match_criteria_t *match_criteria, fido_authenticator_s *auth_info) +{ + _INFO("_get_attestation_type"); + + if (match_criteria && match_criteria->attestation_type_list) { + + GList *match_att_list_iter = g_list_first(match_criteria->attestation_type_list); + while (match_att_list_iter != NULL) { + + int match_att_type = GPOINTER_TO_INT(match_att_list_iter->data); + + if (auth_info && auth_info->attestation_types) { + + GList *auth_att_list_iter = g_list_first(auth_info->attestation_types); + while (auth_att_list_iter != NULL) { + + int auth_att_type = GPOINTER_TO_INT(auth_att_list_iter->data); + + if (match_att_type == auth_att_type) { + _INFO("_get_attestation_type end [%d]", match_att_type); + return match_att_type; + } + } + } + match_att_list_iter = match_att_list_iter->data; + } + } + else { + if (auth_info->attestation_types != NULL) { + GList *att_type_iter = g_list_first(auth_info->attestation_types); + + /*Returning first attestation type in case policy does not mandate any*/ + while (att_type_iter != NULL) { + int auth_att_type = GPOINTER_TO_INT(att_type_iter->data); + _INFO("Returning first attestation type in case policy does not mandate any [%d]", auth_att_type); + return auth_att_type; + } + } + } + + _ERR("_get_attestation_type end"); + return -1; +} + +static char * +__get_verification_method_string(unsigned long int ver_method) +{ + char *ver_str = calloc(1, 128); + + switch (ver_method) { + + case _USER_VER_METHOD_PRESENCE: + snprintf(ver_str, 127, "%s", "Presence Authenticator"); + break; + + case _USER_VER_METHOD_FINGERPRINT: + snprintf(ver_str, 127, "%s", "Fingerprint Authenticator"); + break; + + case _USER_VER_METHOD_PASSCODE: + snprintf(ver_str, 127, "%s", "Passcode Authenticator"); + break; + + case _USER_VER_METHOD_VOICE_PRINT: + snprintf(ver_str, 127, "%s", "Voice Print Authenticator"); + break; + + case _USER_VER_METHOD_FACE_PRINT: + snprintf(ver_str, 127, "%s", "Face Print Authenticator"); + break; + + case _USER_VER_METHOD_LOCATION: + snprintf(ver_str, 127, "%s", "Location Authenticator"); + break; + + case _USER_VER_METHOD_EYE_PRINT: + snprintf(ver_str, 127, "%s", "Eye Print Authenticator"); + break; + + case _USER_VER_METHOD_PATTERN: + snprintf(ver_str, 127, "%s", "Pattern Authenticator"); + break; + + case _USER_VER_METHOD_HAND_PRINT: + snprintf(ver_str, 127, "%s", "Hand Print Authenticator"); + break; + +// case _USER_VER_METHOD_NONE: +// snprintf(ver_str, "%s", ""); +// break; + + case _USER_VER_METHOD_ALL: + snprintf(ver_str, 127, "%s", "All Authenticator"); + break; + + default: + snprintf(ver_str, 127, "%s", "Other Type"); + break; + } + + return ver_str; +} + +static GList* +__copy_string_list(GList *src) +{ + RET_IF_FAIL(src != NULL, NULL); + + GList *dest = NULL; + + GList *iter = g_list_first(src); + while (iter != NULL) { + char *str = (char*)(iter->data); + dest = g_list_append(dest, strdup(str)); + + iter = iter->next; + } + + return dest; +} + +/* Returns _matched_auth_data_t list*/ +GList * +_policy_checker_get_matched_auth_list(_policy_t *policy, GList *auth_list) +{ + _INFO("_policy_checker_get_matched_auth_list"); + + if (policy == NULL) + _INFO("policy is NULL"); + + if (auth_list == NULL) + _INFO("auth_list is NULL"); + + RET_IF_FAIL(policy != NULL, NULL); + RET_IF_FAIL(auth_list != NULL, NULL); + + // _match_criteria_t *match_criteria_or = NULL; + GList *allowed_list = NULL; + GList *disallowed_list = policy->disallowed_list; + GList *accepted_list = policy->accepted_list; + + if (accepted_list != NULL) + _INFO("accepted_list count = [%d]", g_list_length(accepted_list)); + + if (disallowed_list != NULL) + _INFO("allowed_list count = [%d]", g_list_length(disallowed_list)); + + GList *accepted_list_iter = g_list_first(accepted_list); + while (accepted_list_iter != NULL) { + + GList *accepted_list_internal = (GList *) accepted_list_iter->data; + GList *accepted_list_internal_iter = g_list_first(accepted_list_internal); + while (accepted_list_internal_iter != NULL) { + _match_criteria_t *match_info = (_match_criteria_t *) accepted_list_internal_iter->data; + + GList *auth_list_iter = g_list_first(auth_list); + while (auth_list_iter != NULL) { + fido_authenticator_s *authenticator = (fido_authenticator_s*) (auth_list_iter->data); + + if (_policy_checker_is_matched(match_info, authenticator)) { + _INFO("[%s] is matched from allowed list", authenticator->aaid); + + /*Disallowed list can be NULL, which means put all which are matching with accepted list*/ + + if (disallowed_list != NULL) { + + GList *disallowed_list_iter = g_list_first(disallowed_list); + while (disallowed_list_iter != NULL) { + _match_criteria_t *disallowed_match_info = (_match_criteria_t *) disallowed_list_iter->data; + + if (!_policy_checker_is_matched(disallowed_match_info, authenticator)) { + _INFO("[%s] is not in disallowed list", authenticator->aaid); + _matched_auth_data_t *matched_auth_data = (_matched_auth_data_t*) calloc(1, sizeof(_matched_auth_data_t)); + RET_IF_FAIL(matched_auth_data, NULL); + + /*TODO : ASM must send auth index*/ + if (authenticator->auth_index != NULL) + matched_auth_data->auth_index = strdup(authenticator->auth_index); + else + _ERR("auth index missing"); + + matched_auth_data->att_type = _get_attestation_type(match_info, authenticator); + + if (authenticator->title != NULL) + matched_auth_data->label = strdup(authenticator->title); + else { + _ERR("title missing, putting ver method"); + /*If label is null, set verification method name instead*/ + matched_auth_data->label = __get_verification_method_string(authenticator->user_verification); + } + + + if (authenticator->asm_id != NULL) + matched_auth_data->asm_id = strdup(authenticator->asm_id); + else + _ERR("Authenticator does not have any ASM ID!!"); + + matched_auth_data->key_ids = __copy_string_list(match_info->key_id_list); + + allowed_list = g_list_append(allowed_list, matched_auth_data); + } + disallowed_list_iter = disallowed_list_iter->next; + } + } + else { + _INFO("[%s] adding since no disallowed list", authenticator->aaid); + _matched_auth_data_t *matched_auth_data = (_matched_auth_data_t*) calloc(1, sizeof(_matched_auth_data_t)); + RET_IF_FAIL(matched_auth_data, NULL); + + matched_auth_data->auth_index = strdup(authenticator->auth_index); + matched_auth_data->att_type = _get_attestation_type(match_info, authenticator); + if (authenticator->title != NULL) + matched_auth_data->label = strdup(authenticator->title); + else { + _ERR("title missing, putting ver method"); + /*If label is null, set verification method name instead*/ + matched_auth_data->label = __get_verification_method_string(authenticator->user_verification); + } + + if (authenticator->asm_id != NULL) + matched_auth_data->asm_id = strdup(authenticator->asm_id); + else + _ERR("Authenticator does not have any ASM ID!!"); + + matched_auth_data->key_ids = __copy_string_list(match_info->key_id_list); + + allowed_list = g_list_append(allowed_list, matched_auth_data); + } + } + auth_list_iter = auth_list_iter->next; + } + accepted_list_internal_iter = accepted_list_internal_iter->next; + } + accepted_list_iter = accepted_list_iter->next; + } + + if (allowed_list != NULL) + allowed_list = g_list_first(allowed_list); + + return allowed_list; +} + +/* Returns _matched_auth_dereg_t list */ +GList* +_policy_checker_get_matched_auth_list_dereg(const char *app_id, GList *input_auth_list, GList *available_auth_list) +{ + _INFO(""); + + RET_IF_FAIL(app_id, NULL); + RET_IF_FAIL(input_auth_list, NULL); + RET_IF_FAIL(available_auth_list, NULL); + + _INFO(""); + + GList *matched_auth_dereg_list = NULL; + + GList *input_auth_list_iter = g_list_first(input_auth_list); + while (input_auth_list_iter != NULL) { + _dereg_auth_info_t *dereg_auth_info = (_dereg_auth_info_t*) (input_auth_list_iter->data); + + GList *available_auth_list_iter = g_list_first(available_auth_list); + while (available_auth_list_iter != NULL) { + fido_authenticator_s *authenticator = (fido_authenticator_s*) (available_auth_list_iter->data); + + if (dereg_auth_info->aaid != NULL) + _INFO("Input AAID = [%s]", dereg_auth_info->aaid); + + if (authenticator->aaid != NULL) + _INFO("Authenticator AAID = [%s]", authenticator->aaid); + + if (dereg_auth_info->aaid && authenticator->aaid && !strcmp(dereg_auth_info->aaid, authenticator->aaid)) { + _matched_auth_dereg_t *matched_auth_dereg = (_matched_auth_dereg_t*) calloc(1, sizeof(_matched_auth_dereg_t)); + RET_IF_FAIL(matched_auth_dereg, NULL); + + matched_auth_dereg->auth_index = strdup(authenticator->auth_index); + matched_auth_dereg->app_id = strdup(app_id); + matched_auth_dereg->key_id = strdup(dereg_auth_info->key_id); + if (authenticator->asm_id != NULL) + matched_auth_dereg->asm_id = strdup(authenticator->asm_id); + else + _ERR("Authenticator does not have any ASM ID!!"); + + _INFO(""); + matched_auth_dereg_list = g_list_append(matched_auth_dereg_list, matched_auth_dereg); + } + available_auth_list_iter = available_auth_list_iter->next; + } + input_auth_list_iter = input_auth_list_iter->next; + } + + return matched_auth_dereg_list; +} diff --git a/server/fido_uaf_policy_checker.h b/server/fido_uaf_policy_checker.h new file mode 100644 index 0000000..ce9f8b8 --- /dev/null +++ b/server/fido_uaf_policy_checker.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef FIDO_UAF_POLICY_CHECKER_H +#define FIDO_UAF_POLICY_CHECKER_H + +#include +#include +#include "fido_json_handler.h" +#include "fido_internal_types.h" + +bool _policy_checker_is_matched(_match_criteria_t *match_criteria, fido_authenticator_s *auth_info); + +/* Returns _matched_auth_data_t list*/ +GList * _policy_checker_get_matched_auth_list(_policy_t *policy, GList *auth_list); + +/* Returns _matched_auth_dereg_t list*/ +GList * _policy_checker_get_matched_auth_list_dereg(const char *app_id, GList *input_auth_list, GList *available_auth_list); + +#endif // FIDO_UAF_POLICY_CHECKER_H diff --git a/test/Dummy_ASM_DBUS/CMakeLists.txt b/test/Dummy_ASM_DBUS/CMakeLists.txt new file mode 100644 index 0000000..743700a --- /dev/null +++ b/test/Dummy_ASM_DBUS/CMakeLists.txt @@ -0,0 +1,39 @@ +SET(ASM_DAEMON dummyasm-service) + +INCLUDE(FindPkgConfig) +pkg_check_modules(ASM_PKGS REQUIRED + dlog + glib-2.0 + gio-unix-2.0 + capi-base-common + vconf + json-glib-1.0 + capi-appfw-application +) + +FOREACH(flag ${ASM_PKGS_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) + +ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_SOURCE_DIR}/common/dummy-asm-stub.c ${CMAKE_SOURCE_DIR}/common/dummy-asm-stub.h +WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/common/ +COMMAND gdbus-codegen --interface-prefix org.tizen. --generate-c-code dummy-asm-stub ${CMAKE_SOURCE_DIR}/common/dbus_interfaces/dummyasm.xml +COMMENT "Generating Dummy ASM GDBus stubs........................") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror") +SET(CMAKE_LDFLAGS "-Wl,-zdefs") + +SET(DUMMY_ASM_SRCS + dummy_asm_server.c +) + +ADD_EXECUTABLE(${ASM_DAEMON} ${DUMMY_ASM_SRCS} ${CMAKE_SOURCE_DIR}/common/dummy-asm-stub.c) +ADD_DEPENDENCIES(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/common/dummy-asm-stub.h) +ADD_DEPENDENCIES(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/common/dummy-asm-stub.c) + +TARGET_LINK_LIBRARIES(${ASM_DAEMON} ${ASM_PKGS_LDFLAGS}) + +INSTALL(TARGETS ${ASM_DAEMON} DESTINATION bin) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/test/Dummy_ASM_DBUS/dummy_asm.json DESTINATION /usr/lib/fido/asm/) diff --git a/test/Dummy_ASM_DBUS/dummy_asm.json b/test/Dummy_ASM_DBUS/dummy_asm.json new file mode 100644 index 0000000..a34e200 --- /dev/null +++ b/test/Dummy_ASM_DBUS/dummy_asm.json @@ -0,0 +1,8 @@ +{ + "vendor" : "Dummy Corp", + "bin_path" : "/usr/bin/dummyasm-service", + "dbus_info" : "org.tizen.dummyasm", + "dbus_obj_path" : "/org/tizen/dummyasm", + "dbus_interface_name" : "org.tizen.dummyasm", + "dbus_method_name" : "asm_request" +} diff --git a/test/Dummy_ASM_DBUS/dummy_asm_server.c b/test/Dummy_ASM_DBUS/dummy_asm_server.c new file mode 100644 index 0000000..37734d6 --- /dev/null +++ b/test/Dummy_ASM_DBUS/dummy_asm_server.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#if !GLIB_CHECK_VERSION (2, 31, 0) +#include +#endif + +#include +#include "fido_internal_types.h" +#include "fido_logs.h" + +#include "dummy-asm-stub.h" + +#define _DUMMY_ASM_SERVICE_DBUS_PATH "/org/tizen/dummyasm" + +#define _GET_INFO_RESPONSE "{\"responseData\":{\"Authenticators\":[{\"aaid\":\"0001#8001\",\"asmVersions\":[{\"major\":1,\"minor\":0}],\"assertionScheme\":\"UAFV1TLV\",\"title\":\"UAF PIN 1\",\"attestationTypes\":[15879],\"tcDisplayContentType\":\"text/plain\",\"description\":\"Pretty long description\",\"supportedExtensionIDs\":[\"abc\"],\"icon\":\"data:image/png;base64,iVBORw0KGgoAAA\",\"isRoamingAuthenticator\":false,\"isSecondFactorOnly\":false,\"isUserEnrolled\":true,\"keyProtection\":1,\"matcherProtection\":1,\"hasSettings\":true,\"tcDisplay\":1,\"authenticatorIndex\":1,\"authenticationAlgorithm\":1,\"attachmentHint\":1,\"userVerification\":4},{\"aaid\":\"DDDD#C001\",\"asmVersions\":[{\"major\":1,\"minor\":0}],\"assertionScheme\":\"UAFV1TLV\",\"title\":\"UAF PIN 2\",\"attestationTypes\":[15879],\"tcDisplayContentType\":\"text/plain\",\"description\":\"Pretty long description\",\"supportedExtensionIDs\":[\"abc\"],\"icon\":\"data:image/png;base64,iVBORw0KGgoAAA\",\"isRoamingAuthenticator\":false,\"isSecondFactorOnly\":false,\"isUserEnrolled\":true,\"keyProtection\":1,\"matcherProtection\":1,\"hasSettings\":true,\"tcDisplay\":1,\"authenticatorIndex\":2,\"authenticationAlgorithm\":1,\"attachmentHint\":1,\"userVerification\":4}]},\"statusCode\":0}" + +#define _REG_RESPONSE "{\"responseData\":{\"assertion\":\"AT7gAgM-sQALLgkAMDAwMSM4MDAxDi4HAAABAQEAAAEKLiAAbuzkawu9cagRfQWDaOHkQAraLfwuBlCX5WEbQn-2vCQJLiAA1eVp7JIQlwm6YF0YEmGZdNCA27qZoIcZGC0Uaw71bR8NLggAAQAAAAEAAAAMLkEABDvrbVayiXwIsfShzUc2ALT8K3pZKykYGvpD7nU5Jy4sEXEKsepcRfZebCH7RHLwbchz6AmrK-3o1RAbauiuZMcHPicCBi5AAE3tsSOmUITLnQdbRTXdIe2R27E3e3JarZ8MT-9qcZug7__AM5ZUrXqyzSMhRCz9yHEhaeRMyRctxcD18uimqikFLt8BMIIB2zCCAYICCQDDAwxEtwee0TAJBgcqhkjOPQQBMHsxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTELMAkGA1UEBwwCUEExEDAOBgNVBAoMB05OTCxJbmMxDTALBgNVBAsMBERBTjExEzARBgNVBAMMCk5OTCxJbmMgQ0ExHDAaBgkqhkiG9w0BCQEWDW5ubEBnbWFpbC5jb20wHhcNMTQxMjE4MTYwMzEyWhcNMjQxMjE1MTYwMzEyWjByMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCVBhbG8gQWx0bzEbMBkGA1UECgwSTm9rIE5vayBMYWJzLCBJbmMuMSUwIwYJKoZIhvcNAQkBFhZub2tub2tjZXJ0c0Bub2tub2suY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhNa9EIVUCSqfiALGZXM1Zc32gFJfTpGFHIQD5OciVVs4HAl9o1mQOA9WPKhAWH_2dEubn0fQSi1sq4EaOReesjAJBgcqhkjOPQQBA0gAMEUCIHeQm_CRb_joYNff0v9OIzt3FKHvlCZh6ErUldOqUW-UAiEA2kNe-dEqXki2ikfMq79SO7ernvtSZ8X99PuhmMVjxT0\",\"assertionScheme\":\"UAFV1TLV\"},\"statusCode\":0}" + +#define _AUTH_RESPONSE "{\"responseData\":{\"assertion\":\"Aj7WAAQ-jgALLgkAMDAwMSM4MDAxDi4FAAABAQEADy4gAPyMxESI2aTWj7ETwRifnwh3EBOiZdCJDPeFTZuit-ivCi4gABsFkal_ID2-Q2jC0Mtblw4_ApXVeaogzzD-iE3erYUuEC4AAAkuIADV5WnskhCXCbpgXRgSYZl00IDbupmghxkYLRRrDvVtHw0uBAACAAAABi5AAGewExLjMHW0S6iVoHqGzGS8-qGmLfc35WdBSawTDx0rF7sbXUpQQ9LkK4LM-Fu3YgmpEEBXT254dIXbJzr4_oE\",\"assertionScheme\":\"UAFV1TLV\"},\"statusCode\":0}" + +#define _DEREG_RESPONSE "{\"statusCode\" : 0}" + +#define _GET_REGISTRATIONS_RESPONSE "{\"responseData\":{\"appRegs\":[{\"appID\":\"https://qa-egypt.noknoktest.com:443/UAFSampleProxy/uaf/facets.uaf\",\"keyIDs\":[\"1eVp7JIQlwm6YF0YEmGZdNCA27qZoIcZGC0Uaw71bR8\"]}]},\"statusCode\":0}" + +#define _FREEDESKTOP_SERVICE "org.freedesktop.DBus" +#define _FREEDESKTOP_PATH "/org/freedesktop/DBus" +#define _FREEDESKTOP_INTERFACE "org.freedesktop.DBus" + +#define _FIDO_SERVICE_PATH "/usr/bin/fido-service" + +static guint owner_id = 0; + +static Dummyasm* __dbus_obj = NULL; + +static inline int +__read_proc(const char *path, char *buf, int size) +{ + int fd = 0; + int ret = 0; + + if (buf == NULL || path == NULL) { + _ERR("path and buffer is mandatory\n"); + return -1; + } + + fd = open(path, O_RDONLY); + if (fd < 0) { + _ERR("fd open error(%d)\n", fd); + return -1; + } + + ret = read(fd, buf, size - 1); + if (ret <= 0) { + _ERR("fd read error(%d)\n", fd); + close(fd); + return -1; + } else + buf[ret] = 0; + + close(fd); + + return ret; +} + +static char* +__get_proc_path_of_dbus_caller(GDBusMethodInvocation *invocation) +{ + //pid_t remote_pid = 0; + GError *error = NULL; + GDBusConnection *connection = NULL; + GVariant *response = NULL; + guint32 upid; + const gchar *sender = NULL; + + sender = g_dbus_method_invocation_get_sender (invocation); + if (!sender) { + _ERR("Failed to get sender"); + return NULL; + } + + connection = g_dbus_method_invocation_get_connection(invocation); + if (connection == NULL) { + _ERR("Failed to open connection for the invocation [%s]", error->message); + g_error_free (error); + return NULL; + } + + error = NULL; + response = g_dbus_connection_call_sync (connection, + _FREEDESKTOP_SERVICE, _FREEDESKTOP_PATH, + _FREEDESKTOP_INTERFACE, "GetConnectionUnixProcessID", + g_variant_new ("(s)", sender), ((const GVariantType *) "(u)"), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (response == NULL) { + _ERR("Failed to get caller id [%s]", error->message); + g_error_free (error); + return NULL; + } + + g_variant_get (response, "(u)", &upid); + _INFO("Remote msg-bus peer service=%s pid=%u", sender, upid); + //remote_pid = (pid_t) upid; + + g_variant_unref (response); + + char buf[128]; + int ret = 0; + + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", upid); + ret = __read_proc(buf, buf, sizeof(buf)); + if (ret <= 0) { + _ERR("No proc directory (%d)\n", upid); + return NULL; + } + + _INFO("Caller=[%s]", buf); + + return strdup(buf); +} + +static char* +__get_request_type(const char *asm_req_json) +{ + if (asm_req_json == NULL) + return NULL; + + JsonParser *parser = json_parser_new(); + RET_IF_FAIL(parser != NULL, NULL); + + GError *parse_err = NULL; + json_parser_load_from_data(parser, asm_req_json, -1, &parse_err); + RET_IF_FAIL(parse_err == NULL, NULL); + + JsonNode *root = json_parser_get_root(parser); + RET_IF_FAIL(root != NULL, NULL); + + JsonObject *root_obj = json_node_get_object(root); + + const char *req_type = json_object_get_string_member(root_obj, "requestType"); + + return strdup(req_type); + +} + +gboolean +_dbus_on_asm_request(Dummyasm *object, GDBusMethodInvocation *invocation, const gchar *uaf_request_json) +{ + _INFO("_dbus_on_asm_request"); + + char *caller_path = __get_proc_path_of_dbus_caller(invocation); + if (caller_path == NULL) { + _ERR("Failed to get caller path"); + dummyasm_complete_asm_request(object, invocation, -1, NULL); + return true; + } + + if (strcmp(caller_path, _FIDO_SERVICE_PATH) != 0) { + _ERR("Only fido-service is allowed to call ASM"); + dummyasm_complete_asm_request(object, invocation, -1, NULL); + return true; + } + + char *req_type = __get_request_type(uaf_request_json); + if (req_type == NULL){ + dummyasm_complete_asm_request(object, invocation, -1, NULL); + return true; + } + + _INFO("request type=[%s]", req_type); + + if (strcmp(req_type, "GetInfo") == 0){ + dummyasm_complete_asm_request(object, invocation, 0, _GET_INFO_RESPONSE); + } + if (strcmp(req_type, "Register") == 0){ + dummyasm_complete_asm_request(object, invocation, 0, _REG_RESPONSE); + } + if (strcmp(req_type, "Authenticate") == 0){ + dummyasm_complete_asm_request(object, invocation, 0, _AUTH_RESPONSE); + } + if (strcmp(req_type, "Deregister") == 0){ + dummyasm_complete_asm_request(object, invocation, 0, _DEREG_RESPONSE); + } + if (strcmp(req_type, "GetRegistrations") == 0) { + dummyasm_complete_asm_request(object, invocation, 0, _GET_REGISTRATIONS_RESPONSE); + } + + return true; +} + +static void +on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + _INFO("on_bus_acquired"); + + GDBusInterfaceSkeleton* interface = NULL; + __dbus_obj = dummyasm_skeleton_new(); + if (__dbus_obj == NULL) { + return; + } + + interface = G_DBUS_INTERFACE_SKELETON(__dbus_obj); + if (!g_dbus_interface_skeleton_export(interface, connection, _DUMMY_ASM_SERVICE_DBUS_PATH, NULL)) { + return; + } + + _INFO("before g_signal_connect"); + g_signal_connect(__dbus_obj, "handle_asm_request", + G_CALLBACK(_dbus_on_asm_request), NULL); + +} + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + _INFO("on_name_acquired"); +} + +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + _INFO("on_name_lost"); + exit (1); +} + +static bool _initialize_dbus() +{ + _INFO("_initialize_dbus"); + owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, + "org.tizen.dummyasm", + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, + on_name_acquired, + on_name_lost, + NULL, + NULL); + + if(owner_id == 0) { + _INFO("owner_id is 0"); + return false; + } + + + return true; +} + +static void +_initialize(void) +{ +#if !GLIB_CHECK_VERSION(2,35,0) + g_type_init(); +#endif + + if (_initialize_dbus() == false) { + /* because dbus's initialize failed, we cannot continue any more. */ + exit(1); + } +} + +int +main(void) +{ + GMainLoop *mainloop = NULL; + + mainloop = g_main_loop_new(NULL, FALSE); + + _initialize(); + + g_main_loop_run(mainloop); + + + return 0; +} diff --git a/test/FIDOSample/.cproject b/test/FIDOSample/.cproject new file mode 100644 index 0000000..06219c0 --- /dev/null +++ b/test/FIDOSample/.cproject @@ -0,0 +1,557 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/FIDOSample/.exportMap b/test/FIDOSample/.exportMap new file mode 100644 index 0000000..43e310e --- /dev/null +++ b/test/FIDOSample/.exportMap @@ -0,0 +1,4 @@ +{ + global: main; + local: *; +}; diff --git a/test/FIDOSample/.project b/test/FIDOSample/.project new file mode 100644 index 0000000..d420404 --- /dev/null +++ b/test/FIDOSample/.project @@ -0,0 +1,43 @@ + + + FIDOSample + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + org.tizen.nativecore.apichecker.core.builder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.tizen.nativecore.apichecker.core.tizenCppNature + + + + 1432525397806 + + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-matches-false-false-*/.tpk + + + + diff --git a/test/FIDOSample/.rds_delta b/test/FIDOSample/.rds_delta new file mode 100644 index 0000000..612925b --- /dev/null +++ b/test/FIDOSample/.rds_delta @@ -0,0 +1,6 @@ +#delete +#add +#modify +author-signature.xml +signature1.xml +bin/fidosample diff --git a/test/FIDOSample/.sdk_delta.info b/test/FIDOSample/.sdk_delta.info new file mode 100644 index 0000000..800f1fa Binary files /dev/null and b/test/FIDOSample/.sdk_delta.info differ diff --git a/test/FIDOSample/.sign/.manifest.tmp b/test/FIDOSample/.sign/.manifest.tmp new file mode 100644 index 0000000..4172b97 --- /dev/null +++ b/test/FIDOSample/.sign/.manifest.tmp @@ -0,0 +1,14 @@ +bin/fidosample__DEL__cQydzVGXaqxCtCMUHVsORDV8JNjErEzMdsV0NBqLjTM= +lib/libfido.so__DEL__P2ULaW6DujYXBTB+zl0+20pyk4TjC/Ns6/agEF+uIXk= +lib/libfido.so.0__DEL__P2ULaW6DujYXBTB+zl0+20pyk4TjC/Ns6/agEF+uIXk= +lib/libfido.so.0.0.1__DEL__P2ULaW6DujYXBTB+zl0+20pyk4TjC/Ns6/agEF+uIXk= +res/auth_req.json__DEL__FGdxCabhGQXxZ5gkxsFI4jR5ZOxn4ZXDReerTH0Bm4E= +res/dereg_req.json__DEL__jX5V0X77th7FzuRnTCqo31VTnusBJTVU8Zz4nKSlQYs= +res/images/grid_image/1_raw.png__DEL__IJNLOq/2eGlWpHGmr+9Mr8bWDbnm0RohlK0cMHO8jZU= +res/images/grid_image/2_raw.png__DEL__S9L9E5QpM5gu7cRg8B4Y+030ULCkfPBJA4gMdIHuyCw= +res/images/horz_scrollbar.png__DEL__ZJMOojE8pcti4mJJDD/iNw8d0k139TVGwzwEpGNbNyQ= +res/images/iu.png__DEL__iLwO5Bzet3XJ6+hLP5KGoIsFcgDFFICC19Pk+JGz4is= +res/reg_req.json__DEL__VVAmN7Zvyj11MUk8/3f+YVfpSh8TK1iZCQmUUTl68D0= +shared/res/fidosample.png__DEL__1d0oEZHqPn+QzNzGIHwj9ODby6x9ggFs9uOsav6jPNs= +tizen-manifest.xml__DEL__lpZcIwMWbCWgkT+mRmx6DdJlsq3wr+rXPssOdJEbRPI= +author-signature.xml__DEL__lpGJZnRZJh1VLsq1P4tx2rnjqn6GshHqgmxx+NaGCTk= diff --git a/test/FIDOSample/.sign/author-signature.xml b/test/FIDOSample/.sign/author-signature.xml new file mode 100644 index 0000000..38409cb --- /dev/null +++ b/test/FIDOSample/.sign/author-signature.xml @@ -0,0 +1,106 @@ + + + + + + +cQydzVGXaqxCtCMUHVsORDV8JNjErEzMdsV0NBqLjTM= + + + +P2ULaW6DujYXBTB+zl0+20pyk4TjC/Ns6/agEF+uIXk= + + + +P2ULaW6DujYXBTB+zl0+20pyk4TjC/Ns6/agEF+uIXk= + + + +P2ULaW6DujYXBTB+zl0+20pyk4TjC/Ns6/agEF+uIXk= + + + +FGdxCabhGQXxZ5gkxsFI4jR5ZOxn4ZXDReerTH0Bm4E= + + + +jX5V0X77th7FzuRnTCqo31VTnusBJTVU8Zz4nKSlQYs= + + + +IJNLOq/2eGlWpHGmr+9Mr8bWDbnm0RohlK0cMHO8jZU= + + + +S9L9E5QpM5gu7cRg8B4Y+030ULCkfPBJA4gMdIHuyCw= + + + +ZJMOojE8pcti4mJJDD/iNw8d0k139TVGwzwEpGNbNyQ= + + + +iLwO5Bzet3XJ6+hLP5KGoIsFcgDFFICC19Pk+JGz4is= + + + +VVAmN7Zvyj11MUk8/3f+YVfpSh8TK1iZCQmUUTl68D0= + + + +1d0oEZHqPn+QzNzGIHwj9ODby6x9ggFs9uOsav6jPNs= + + + +lpZcIwMWbCWgkT+mRmx6DdJlsq3wr+rXPssOdJEbRPI= + + + + + + +lpo8tUDs054eLlBQXiDPVDVKfw30ZZdtkRs1jd7H5K8= + + + +Nk/gxrB8EQzeGZzVzoShWf/pYdIkX+39TG7MAGkqtRBfeZPPr9+HV7sU47lYwzwGaVhw5VD4sSFg +Je27t7tKhfUHuTaD4FxITZRJPPALPEztKGOEEtf7sDKVZXafSv2/WNlC4Ogg7jVKPLJ6yxxYJkDf +Y6UN6bU7t60HPB4FoNg= + + + + +MIIClTCCAX2gAwIBAgIGAU2fJWlKMA0GCSqGSIb3DQEBBQUAMFYxGjAYBgNVBAoMEVRpemVuIEFz +c29jaWF0aW9uMRowGAYDVQQLDBFUaXplbiBBc3NvY2lhdGlvbjEcMBoGA1UEAwwTVGl6ZW4gRGV2 +ZWxvcGVycyBDQTAeFw0xMjExMDEwMDAwMDBaFw0xOTAxMDEwMDAwMDBaMBExDzANBgNVBAMMBmF1 +dGhvcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2VQLCgvKZSz4D3K5fzI8xDObQhn0CZmD +f2rQdfPgc0WbaKRHgOaQ4WZ5xxyqtEmVxXRU0W7KeylUfbxaDzibmqtq4lV2eCZ7XLW1nW4OwXil +SSFTkNjgYI4HTmwO2YzRP5Y+uw3Ljl30o7YxkhpO2b7w4OJASxAMB9/Em1n1R20CAwEAAaMyMDAw +DAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcN +AQEFBQADggEBAJx+sGPyiDI8km5hGA29XkvOcOn41XJRMHv7s28MHIvg5j8qkQNJneq8sc7ilMNo +0V1Zize3+1XtpdAAI4xPsA6DUGzCX002lieRefwUVKvCv4ETknkuZ4OdjkQrrBGHBGzCV0QWv6o4 +FX0Ep2XoMLHiRSI4ATutUYc9+uehQPuWkzrRSR3SbvEaS2hu3GoFCl7Enc6Y7Ebfn1LgEW13i6hO +sbKhFc0lyHYyk+2MnhpB/SpQszRv0zOs1j6aVy8afozaBP2kS+/OgJ4XYaaNVreLIoRg1GmZhYzF +NJ4p4t7Z83GuS0SjxnfVVNNT19utuDJX8ay5334I+v7fPvVlN8g= + + +MIIDOTCCAiGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMRowGAYDVQQKDBFUaXplbiBBc3NvY2lh +dGlvbjEaMBgGA1UECwwRVGl6ZW4gQXNzb2NpYXRpb24xHjAcBgNVBAMMFVRpemVuIERldmVsb3Bl +cnMgUm9vdDAeFw0xMjAxMDEwMDAwMDBaFw0yNzAxMDEwMDAwMDBaMFYxGjAYBgNVBAoMEVRpemVu +IEFzc29jaWF0aW9uMRowGAYDVQQLDBFUaXplbiBBc3NvY2lhdGlvbjEcMBoGA1UEAwwTVGl6ZW4g +RGV2ZWxvcGVycyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANVGhRGmMIUyBA7o +PCz8Sxut6z6HNkF4oDIuzuKaMzRYPeWodwe9O0gmqAkToQHfwg2giRhE5GoPld0fq+OYMMwSasCu +g8dwODx1eDeSYVuOLWRxpAmbTXOsSFi6VoWeyaPEm18JBHvZBsU5YQtgZ6Kp7MqzvQg3pXOxtajj +vyHxiatJl+xXrHgcXC1wgyG3buty7u/Fi2mvKXJ0PRJcCjjK81dqe/Vr20sRUCrbk02zbm5ggFt/ +jIEhV8wbFRQpliobc7J4dSTKhFfrqGM8rdd54LYhD7gSI1CFSe16pUXfcVR7FhJztRaiGLnCrwBE +dyTZ248+D4L/qR/D0axb3jcCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC +AQEAnOXXQ/1O/QTDHyrmQDtFziqPY3xWlJBqJtEqXiT7Y+Ljpe66e+Ee/OjQMlZe8gu21/8cKklH +95RxjopMWCVedXDUbWdvS2+CdyvVW/quT2E0tjqIzXDekUTYwwhlPWlGxvfj3VsxqSFq3p8Brl04 +1Gx5RKAGyKVsMfTLhbbwSWwApuBUxYfcNpKwLWGPXkysu+HctY03OKv4/xKBnVWiN8ex/Sgesi0M ++OBAOMdZMPK32uJBTeKFx1xZgTLIhk45V0hPOomPjZloiv0LSS11eyd451ufjW0iHRE7WlpR6EvI +W6TFyZgMpQq+kg4hWl2SBTf3s2VI8Ygz7gj8TMlClg== + + + + + \ No newline at end of file diff --git a/test/FIDOSample/.sign/signature1.xml b/test/FIDOSample/.sign/signature1.xml new file mode 100644 index 0000000..b7770f0 --- /dev/null +++ b/test/FIDOSample/.sign/signature1.xml @@ -0,0 +1,108 @@ + + + + + + +lpGJZnRZJh1VLsq1P4tx2rnjqn6GshHqgmxx+NaGCTk= + + + +cQydzVGXaqxCtCMUHVsORDV8JNjErEzMdsV0NBqLjTM= + + + +P2ULaW6DujYXBTB+zl0+20pyk4TjC/Ns6/agEF+uIXk= + + + +P2ULaW6DujYXBTB+zl0+20pyk4TjC/Ns6/agEF+uIXk= + + + +P2ULaW6DujYXBTB+zl0+20pyk4TjC/Ns6/agEF+uIXk= + + + +FGdxCabhGQXxZ5gkxsFI4jR5ZOxn4ZXDReerTH0Bm4E= + + + +jX5V0X77th7FzuRnTCqo31VTnusBJTVU8Zz4nKSlQYs= + + + +IJNLOq/2eGlWpHGmr+9Mr8bWDbnm0RohlK0cMHO8jZU= + + + +S9L9E5QpM5gu7cRg8B4Y+030ULCkfPBJA4gMdIHuyCw= + + + +ZJMOojE8pcti4mJJDD/iNw8d0k139TVGwzwEpGNbNyQ= + + + +iLwO5Bzet3XJ6+hLP5KGoIsFcgDFFICC19Pk+JGz4is= + + + +VVAmN7Zvyj11MUk8/3f+YVfpSh8TK1iZCQmUUTl68D0= + + + +1d0oEZHqPn+QzNzGIHwj9ODby6x9ggFs9uOsav6jPNs= + + + +lpZcIwMWbCWgkT+mRmx6DdJlsq3wr+rXPssOdJEbRPI= + + + + + + +u/jU3U4Zm5ihTMSjKGlGYbWzDfRkGphPPHx3gJIYEJ4= + + + +R08hPToKjQBKyVXqEKXuXaVYQk6JguHXCUQ/CLB3X1aS1ObBO48mrpptk6nJnnuguhMn7rlyiIcn +1e4QJnOnZ4yZzlTT0sPQ7AcVJBGeI8uX8p4RFwhpVhuZm8LWYrpN5BhIUqSPAFIQafeSOPkFfmFr +jaVnxuK+lNDT75vMXi8= + + + + +MIICmzCCAgQCCQDXI7WLdVZwiTANBgkqhkiG9w0BAQUFADCBjzELMAkGA1UEBhMCS1IxDjAMBgNV +BAgMBVN1d29uMQ4wDAYDVQQHDAVTdXdvbjEWMBQGA1UECgwNVGl6ZW4gVGVzdCBDQTEiMCAGA1UE +CwwZVGl6ZW4gRGlzdHJpYnV0b3IgVGVzdCBDQTEkMCIGA1UEAwwbVGl6ZW4gUHVibGljIERpc3Ry +aWJ1dG9yIENBMB4XDTEyMTAyOTEzMDMwNFoXDTIyMTAyNzEzMDMwNFowgZMxCzAJBgNVBAYTAktS +MQ4wDAYDVQQIDAVTdXdvbjEOMAwGA1UEBwwFU3V3b24xFjAUBgNVBAoMDVRpemVuIFRlc3QgQ0Ex +IjAgBgNVBAsMGVRpemVuIERpc3RyaWJ1dG9yIFRlc3QgQ0ExKDAmBgNVBAMMH1RpemVuIFB1Ymxp +YyBEaXN0cmlidXRvciBTaWduZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALtMvlc5hENK +90ZdA+y66+Sy0enD1gpZDBh5T9RP0oRsptJv5jjNTseQbQi0SZOdOXb6J7iQdlBCtR343RpIEz8H +mrBy7mSY7mgwoU4EPpp4CTSUeAuKcmvrNOngTp5Hv7Ngf02TTHOLK3hZLpGayaDviyNZB5PdqQdB +hokKjzAzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAvGp1gxxAIlFfhJH1efjb9BJK/rtRkbYn9+Ez +GEbEULg1svsgnyWisFimI3uFvgI/swzr1eKVY3Sc8MQ3+Fdy3EkbDZ2+WAubhcEkorTWjzWz2fL1 +vKaYjeIsuEX6TVRUugHWudPzcEuQRLQf8ibZWjbQdBmpeQYBMg5x+xKLCJc= + + +MIICtDCCAh2gAwIBAgIJAMDbehElPNKvMA0GCSqGSIb3DQEBBQUAMIGVMQswCQYDVQQGEwJLUjEO +MAwGA1UECAwFU3V3b24xDjAMBgNVBAcMBVN1d29uMRYwFAYDVQQKDA1UaXplbiBUZXN0IENBMSMw +IQYDVQQLDBpUVGl6ZW4gRGlzdHJpYnV0b3IgVGVzdCBDQTEpMCcGA1UEAwwgVGl6ZW4gUHVibGlj +IERpc3RyaWJ1dG9yIFJvb3QgQ0EwHhcNMTIxMDI5MTMwMjUwWhcNMjIxMDI3MTMwMjUwWjCBjzEL +MAkGA1UEBhMCS1IxDjAMBgNVBAgMBVN1d29uMQ4wDAYDVQQHDAVTdXdvbjEWMBQGA1UECgwNVGl6 +ZW4gVGVzdCBDQTEiMCAGA1UECwwZVGl6ZW4gRGlzdHJpYnV0b3IgVGVzdCBDQTEkMCIGA1UEAwwb +VGl6ZW4gUHVibGljIERpc3RyaWJ1dG9yIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDe +OTS/3nXvkDEmsFCJIvRlQ3RKDcxdWJJp625pFqHdmoJBdV+x6jl1raGK2Y1sp2Gdvpjc/z92yzAp +bE/UVLPh/tRNZPeGhzU4ejDDm7kzdr2f7Ia0U98K+OoY12ucwg7TYNItj9is7Cj4blGfuMDzd2ah +2AgnCGlwNwV/pv+uVQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBACqJ +KO33YdoGudwanZIxMdXuxnnD9R6u72ltKk1S4zPfMJJv482CRGCI4FK6djhlsI4i0Lt1SVIJEed+ +yc3qckGm19dW+4xdlkekon7pViEBWuyHw8OWv3RXtTum1+PGHjBJ2eYY4ZKIpz73U/1NC16sTB/0 +VhfnkHwPltmrpYVe + + + + + \ No newline at end of file diff --git a/test/FIDOSample/.tproject b/test/FIDOSample/.tproject new file mode 100644 index 0000000..801d1ed --- /dev/null +++ b/test/FIDOSample/.tproject @@ -0,0 +1,11 @@ + + + + + mobile-2.4 + + + + + + diff --git a/test/FIDOSample/edje/images/00_controlbar_icon_artists.png b/test/FIDOSample/edje/images/00_controlbar_icon_artists.png new file mode 100644 index 0000000..85dd55c Binary files /dev/null and b/test/FIDOSample/edje/images/00_controlbar_icon_artists.png differ diff --git a/test/FIDOSample/edje/images/00_controlbar_icon_dialer.png b/test/FIDOSample/edje/images/00_controlbar_icon_dialer.png new file mode 100644 index 0000000..5dbb9fe Binary files /dev/null and b/test/FIDOSample/edje/images/00_controlbar_icon_dialer.png differ diff --git a/test/FIDOSample/edje/images/00_controlbar_icon_favorites.png b/test/FIDOSample/edje/images/00_controlbar_icon_favorites.png new file mode 100644 index 0000000..663b6fa Binary files /dev/null and b/test/FIDOSample/edje/images/00_controlbar_icon_favorites.png differ diff --git a/test/FIDOSample/edje/images/00_controlbar_icon_playlist.png b/test/FIDOSample/edje/images/00_controlbar_icon_playlist.png new file mode 100644 index 0000000..cb77f2b Binary files /dev/null and b/test/FIDOSample/edje/images/00_controlbar_icon_playlist.png differ diff --git a/test/FIDOSample/edje/images/00_controlbar_icon_songs.png b/test/FIDOSample/edje/images/00_controlbar_icon_songs.png new file mode 100644 index 0000000..b47daf3 Binary files /dev/null and b/test/FIDOSample/edje/images/00_controlbar_icon_songs.png differ diff --git a/test/FIDOSample/edje/images/core_button_add.png b/test/FIDOSample/edje/images/core_button_add.png new file mode 100644 index 0000000..d2b5db5 Binary files /dev/null and b/test/FIDOSample/edje/images/core_button_add.png differ diff --git a/test/FIDOSample/edje/images/core_button_delete.png b/test/FIDOSample/edje/images/core_button_delete.png new file mode 100644 index 0000000..37d3e5f Binary files /dev/null and b/test/FIDOSample/edje/images/core_button_delete.png differ diff --git a/test/FIDOSample/edje/images/core_color_picker_palette.png b/test/FIDOSample/edje/images/core_color_picker_palette.png new file mode 100644 index 0000000..497cc75 Binary files /dev/null and b/test/FIDOSample/edje/images/core_color_picker_palette.png differ diff --git a/test/FIDOSample/edje/images/core_icon_brightness.png b/test/FIDOSample/edje/images/core_icon_brightness.png new file mode 100644 index 0000000..f7dfb29 Binary files /dev/null and b/test/FIDOSample/edje/images/core_icon_brightness.png differ diff --git a/test/FIDOSample/edje/images/grid_image/1_raw.jpg b/test/FIDOSample/edje/images/grid_image/1_raw.jpg new file mode 100644 index 0000000..94deef3 Binary files /dev/null and b/test/FIDOSample/edje/images/grid_image/1_raw.jpg differ diff --git a/test/FIDOSample/edje/images/grid_image/2_raw.jpg b/test/FIDOSample/edje/images/grid_image/2_raw.jpg new file mode 100644 index 0000000..3438b54 Binary files /dev/null and b/test/FIDOSample/edje/images/grid_image/2_raw.jpg differ diff --git a/test/FIDOSample/edje/images/horz_scrollbar.jpg b/test/FIDOSample/edje/images/horz_scrollbar.jpg new file mode 100644 index 0000000..ab27b96 Binary files /dev/null and b/test/FIDOSample/edje/images/horz_scrollbar.jpg differ diff --git a/test/FIDOSample/edje/images/iu.jpg b/test/FIDOSample/edje/images/iu.jpg new file mode 100644 index 0000000..38586e9 Binary files /dev/null and b/test/FIDOSample/edje/images/iu.jpg differ diff --git a/test/FIDOSample/edje/images/logo.png b/test/FIDOSample/edje/images/logo.png new file mode 100644 index 0000000..f7f7b2d Binary files /dev/null and b/test/FIDOSample/edje/images/logo.png differ diff --git a/test/FIDOSample/inc/main.h b/test/FIDOSample/inc/main.h new file mode 100644 index 0000000..6514cba --- /dev/null +++ b/test/FIDOSample/inc/main.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "org.tizen.Fidosample" + +#define KEY_END "XF86Stop" + +#if !defined(PACKAGE) +#define PACKAGE "org.tizen.fidosample" +#endif + +#define ELM_DEMO_EDJ "/opt/usr/apps/org.tizen.fidosample/res/ui_controls.edj" +#define ICON_DIR "/opt/usr/apps/org.tizen.fidosample/res/images" + + +typedef struct appdata { + Evas_Object *win; + Evas_Object *conform; + Evas_Object *layout; + Evas_Object *nf; + Evas_Object *datetime; + Evas_Object *popup; + Evas_Object *button; + struct tm saved_time; +} appdata_s; + +void start_discover(void *data, Evas_Object *obj, void *event_info); +void start_check_policy(void *data, Evas_Object *obj, void *event_info); +void start_registration(void *data, Evas_Object *obj, void *event_info); +void start_auth(void *data, Evas_Object *obj, void *event_info); +void start_de_registration(void *data, Evas_Object *obj, void *event_info); diff --git a/test/FIDOSample/res/auth_req.json b/test/FIDOSample/res/auth_req.json new file mode 100644 index 0000000..ea3aa06 --- /dev/null +++ b/test/FIDOSample/res/auth_req.json @@ -0,0 +1,92 @@ +[ + { + "header": { + "upv": { + "major": 1, + "minor": 0 + }, + "op": "Auth", + "appID": "org.tizen.FidoSample", + "serverData": "emKubKMS8RxYOth7J8enT_x7dQWBaO1CiC0fGmSEhX56kq2RYo1LRpwvfHlzYRI3p9Ay-l4zJcV3lX6rQ0CYNWi5nNDabClFm3k0pPj0kX5V-db9ejN_05y2J6wqztSD" + }, + "challenge": "1AM2yZY4-9SG4Ns7-hMdB8IV_FTDKFFiUqNJNVbsVoo", + "transaction": [ + { + "contentType": "image/png", + "content": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE8AAAAvCAYAAACiwJfcAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAahSURBVGhD7Zr5bxRlGMf9KzTB8AM/YEhE2W7pQZcWKKBclSpHATlELARE7kNECCA3FkWK0CKKSCFIsKBcgVCDWGNESdAYidwgggJBiRiMhFc/4wy8884zu9NdlnGTfZJP2n3nO++88933fveBBx+PqCzJkTUvBbLmpUDWvBTImpcCSZvXLCdX9R05Sk19bb5atf599fG+/erA541q47aP1LLVa9SIyVNUi8Ii8d5kGTsi30NFv7ai9n7QZPMwbdys2erU2XMqUdy8+ZcaNmGimE8yXN3RUd3a18nF0fUlovZ+0CTzWpd2Vj+eOm1bEyy6Dx4i5pUMGWveo506q227dtuWBIuffr6oWpV0FPNLhow1751Nm21LvPH3rVtWjfz66Lfql8tX7FRl9YFSXsmSseb9ceOGbYk7MNUcGPg8ZsbMe9rfQUaaV/JMX9sqdzDCSvp0kZHmTZg9x7bLHcMnThb16eJ+mVfQq8yaUZQNG64iXZ+0/kq6uOZFO0QtatdWKfXnRQ99Bj91R5OIFnk54jN0mkUiqlO3XDW+Ml+98mKB6tW7rWpZcPc+0zg4tLrYlUc86E6eGDjIMubVpcusearfgIYGRk6brhZVr/JcHzooL7550jedLExopWcApi2ZUqhu7JLvrVsQU81zkzOPeemMRYvVuQsX7PbiDQY5JvZonftK+1VY8H9utx530h0ob+jmRYqj6ouaYvEenW/WlYjp8cwbMm682tPwqW1R4tj/2SH13IRJYl4moZvXpiSqDr7dXtQHxa/PK3/+BWsK1dTgHu6V8tQJ3bwFkwpFrUOQ50s1r3levm8zZcq17+BBaw7K8lEK5qzkYeark9A8p7P3GzDK+nd3DQow+6UC8SVN82iuv38im7NtaXtV1CVq6Rgw4pksmbdi3bu2De7YfaBBxcqfvqPrUjFQNTQ22lfdUVVT68rTJKF5DnSmUjgdqg4mSS9pmsfDJR3G6ToH0iW9aV7LWLHYXKllTDt0LTAtkYIaamp1QjVv++uyGUxVdJ0DNVXSm+b1qRxpl84ddfX1Lp1O/d69tsod0vs5hGre9xu8o+fpLR1cGhNTD6Z57C9KMWXefJdOZ94bb9oqd1ROnS7qITTzHimMqivbO3g0DdVyk3WQBhBztK35YKNdOnc8O3acS6fDZFgKaXLsEJp5rdrliBqp89cJcs/m7Tvs0rkjGfN4b0kPoZn3UJuIOrnZ22yP1fmvUx+O5gSqebV1m+zSuYNVhq7TWbDiLVvljplLlop6CLXP+2qtvGLIL/1vimISdMBgzSoFZyu6Tqd+jzxgsPaV9BCqee/NjYk6v6lK9cwiUc/STtf1HDpM3b592y7h3Thx5ozK69HLpYWuAwaqS5cv26q7ceb8efVYaReP3iFU8zj1knSwZXHMmnCjY0Ogalo7UQfSCM3qQQr2H/XFP7ssXx45Yl91ByeCep4moZoH+1fG3xD4tT7x8kwyj8nwb9ev26V0B6d+7H4zKvudAH537FjqyzOHdJnHEuzmXq/WjxObvNMbv7nhywsX2aVsWtC8+48aLeapE7p5wKZi0A2AQRV5nvR4E+uJc+b61kApqInxBgmd/4V5QP/mt18HDC7sRHftmeu5lmhV0rn/ALX232bqd4BFnDx7Vi1cWS2uff0IbB47qexxmUj9QutYjupd3tYD6abWBBMrh+apNbOKrNF1+ugCa4riXGfwMPPtViavhU3YMOAAnuUb/R07L0yOSeOadE88ApsXFGff30ynhlJgM51CU6vN9EzgnpvHBFUyiVraePiwJ53DF5ZTZnomENg85kNUd2oJi2Wpr4OmmkfN4x4zHfiVFc8Dv8NzuhNqOidilGvA6DGueZwO78AAQn6ciEk6+rw5VcvjvqNDYPOoIUwaKShrxAuXLlkH4aYuGfMYDc10WF5Ta31hPJOfcUhrU/JlINi6c6elRYdBpo6++Yfjx61lGNfRm4MD5rJ1j3FoGHnjDSBNarYUgMLyMszKpb7tXpoHfPs8h3Wp1LzNfNk54XxC1wDGUmYzXYefh6z/cKtVm4EBxa9VQGDzYr3LrUMRjHEKkk7zaFKYQA2hGQU1z+85NFWpXDrkz3vx10GqxQ6BzeNboBk5n8k4nebRh+k1hWfxTF0D1EyWUs5nv+dgQqKaxzuCdE0isHl02NQ8ah0mXr12La3m0f9wik9+wLNTMY/86MPo8yi31OfxmT6PWoqG9+DZukYna56mSZt5WWSy5qVA1rwUyJqXAlnzkiai/gHSD7RkTyihogAAAABJRU5ErkJggg==", + "tcDisplayPNGCharacteristics": [ + { + "width": 320, + "height": 240, + "bitDepth": 16, + "colorType": 2, + "compression": 0, + "filter": 0, + "interlace": 0 + } + ] + } + ], + "policy": { + "accepted": [ + [ + { + "aaid": [ + "53EC#C002" + ] + } + ], + [ + { + "aaid": [ + "371D#0001" + ] + } + ], + [ + { + "aaid": [ + "0001#8001" + ] + } + ], + [ + { + "aaid": [ + "138A#4202" + ] + } + ], + [ + { + "aaid": [ + "138A#6102" + ] + } + ], + [ + { + "aaid": [ + "138A#7501" + ] + } + ], + [ + { + "aaid": [ + "138A#7502" + ] + } + ], + [ + { + "aaid": [ + "ABCD#ABCD" + ] + } + ] + ] + } + } +] + diff --git a/test/FIDOSample/res/dereg_req.json b/test/FIDOSample/res/dereg_req.json new file mode 100644 index 0000000..0332a54 --- /dev/null +++ b/test/FIDOSample/res/dereg_req.json @@ -0,0 +1 @@ +[{"header":{"upv":{"major":1,"minor":0},"op":"Dereg","appID":"org.tizen.fidosample"},"authenticators":[{"aaid":"53EC#C002","keyID":"zsfjhbCwYi_w-zHTiFvJj7cv-siLlds5DaqhxS9Wt9Y="}]}] diff --git a/test/FIDOSample/res/images/grid_image/1_raw.png b/test/FIDOSample/res/images/grid_image/1_raw.png new file mode 100644 index 0000000..435b065 Binary files /dev/null and b/test/FIDOSample/res/images/grid_image/1_raw.png differ diff --git a/test/FIDOSample/res/images/grid_image/2_raw.png b/test/FIDOSample/res/images/grid_image/2_raw.png new file mode 100644 index 0000000..4939953 Binary files /dev/null and b/test/FIDOSample/res/images/grid_image/2_raw.png differ diff --git a/test/FIDOSample/res/images/horz_scrollbar.png b/test/FIDOSample/res/images/horz_scrollbar.png new file mode 100644 index 0000000..a402da7 Binary files /dev/null and b/test/FIDOSample/res/images/horz_scrollbar.png differ diff --git a/test/FIDOSample/res/images/iu.png b/test/FIDOSample/res/images/iu.png new file mode 100644 index 0000000..3a1e2d7 Binary files /dev/null and b/test/FIDOSample/res/images/iu.png differ diff --git a/test/FIDOSample/res/reg_req.json b/test/FIDOSample/res/reg_req.json new file mode 100644 index 0000000..9c76c20 --- /dev/null +++ b/test/FIDOSample/res/reg_req.json @@ -0,0 +1 @@ +[{"header":{"upv":{"major":1,"minor":0},"op":"Reg","appID":"org.tizen.fidosample","serverData":"nwV8EPqS5raZdAgH3GD9Z-ytCA9MkiiWaCsr1GHHNJ2yUh3HaV1HHxd4Z67FefJOD5sQYZvipfg5BavhdWPMecD2SH39aJixoXN9ZaNwRlcftJe9WbtPNDC9q5V9WX7Z5jCwkAwehcI"},"challenge":"9pIcUwwrY5eD9o3OwfhkeHLnoIl0vaeJUbxSHMe_XgE","username":"ryan","policy":{"accepted":[[{"aaid":["ABCD#DEFG"]}],[{"aaid":["53EC#C002"]}],[{"aaid":["0001#8001"]}],[{"aaid":["138A#4202"]}],[{"aaid":["138A#6102"]}],[{"aaid":["138A#7501"]}],[{"aaid":["138A#7502"]}],[{"aaid":["ABCD#ABCD"]}]],"disallowed":[{"aaid":["138A#4202"],"keyIDs":["nPuYmaADw0wV09TfZo5Y1HjXpz3IjnBI3aPizY5XrfU","dWCWB0YIE_k_0QinMCYuS5HnPS5h6F76PGPgs5wyoeQ"]}]}}] diff --git a/test/FIDOSample/shared/res/fidosample.png b/test/FIDOSample/shared/res/fidosample.png new file mode 100644 index 0000000..9765b1b Binary files /dev/null and b/test/FIDOSample/shared/res/fidosample.png differ diff --git a/test/FIDOSample/src/main.c b/test/FIDOSample/src/main.c new file mode 100755 index 0000000..9b10474 --- /dev/null +++ b/test/FIDOSample/src/main.c @@ -0,0 +1,681 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "main.h" +#include "fido.h" +#include +#include + +#define _REG_REQ_FILE_NAME "/opt/usr/apps/org.tizen.fidosample/res/reg_req.json" +#define _AUTH_REQ_FILE_NAME "/opt/usr/apps/org.tizen.fidosample/res/auth_req.json" +#define _DEREG_REQ_FILE_NAME "/opt/usr/apps/org.tizen.fidosample/res/dereg_req.json" + +static char *json_reg = NULL; +static char *json_auth = NULL; +static char *json_dereg = NULL; + +static char* +__read(const char *file_name) +{ + FILE *file = fopen(file_name, "rb"); + if (file == NULL) + return NULL; + + fseek(file, 0, SEEK_END); + long size = ftell(file); + if (size <= 0) { + fclose(file); + return NULL; + } + + fseek(file, 0, SEEK_SET); + + char *json = calloc(1, size + 1); + int num_bytes = fread(json, size, 1, file); + if (num_bytes <= 0) { + free(json); + fclose(file); + return NULL; + } + + json[size] = 0; + + fclose(file); + + return json; + +} + +static void _response_cb(void *data, Evas_Object *obj, void *event_info) +{ + evas_object_del(data); +} + +static void create_popup(char *popup_str, appdata_s *ad) +{ + Evas_Object *popup = elm_popup_add(ad->win); + Evas_Object *btn; + char str[2048] = {0,}; + strcpy(str,popup_str); + elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(popup, popup_str); + + btn = elm_button_add(popup); + elm_object_style_set(btn, "popup"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(btn, "OK"); + elm_object_part_content_set(popup, "button1", btn); + eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL); + evas_object_smart_callback_add(btn, "clicked", _response_cb, popup); + evas_object_show(popup); + + return; +} + +char *get_error_code(fido_error_e error_code) +{ + + char *error_str = calloc(1,128); + + if(error_code == FIDO_ERROR_NONE) + strcpy(error_str, "SUCCESS"); + else if (error_code == FIDO_ERROR_OUT_OF_MEMORY) + strcpy(error_str, "FIDO_ERROR_OUT_OF_MEMORY"); + else if (error_code == FIDO_ERROR_INVALID_PARAMETER) + strcpy(error_str, "FIDO_ERROR_INVALID_PARAMETER"); + else if (error_code == FIDO_ERROR_NO_DATA) + strcpy(error_str, "FIDO_ERROR_NO_DATA"); + else if (error_code == FIDO_ERROR_PERMISSION_DENIED) + strcpy(error_str, "FIDO_ERROR_PERMISSION_DENIED"); + else if (error_code == FIDO_ERROR_NOT_SUPPORTED) + strcpy(error_str, "FIDO_ERROR_NOT_SUPPORTED"); + else if (error_code == FIDO_ERROR_USER_ACTION_IN_PROGRESS) + strcpy(error_str, "FIDO_ERROR_USER_ACTION_IN_PROGRESS"); + else if (error_code == FIDO_ERROR_USER_CANCELLED) + strcpy(error_str, "FIDO_ERROR_USER_CANCELLED"); + else if (error_code == FIDO_ERROR_UNSUPPORTED_VERSION) + strcpy(error_str, "FIDO_ERROR_UNSUPPORTED_VERSION"); + else if (error_code == FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR) + strcpy(error_str, "FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR"); + else if (error_code == FIDO_ERROR_PROTOCOL_ERROR) + strcpy(error_str, "FIDO_ERROR_PROTOCOL_ERROR"); + else if (error_code == FIDO_ERROR_UNTRUSTED_FACET_ID) + strcpy(error_str, "FIDO_ERROR_UNTRUSTED_FACET_ID"); + else + strcpy(error_str, "FIDO_ERROR_UNKNOWN"); + return error_str; +} + +void uaf_version_cb(fido_version_h version, void *user_data) +{ + char *str = (char *) user_data; + + char tmp[1024] = {0,}; + int major = -1; + int minor = -1; + + fido_get_uaf_version(version, &major, &minor); + if(major != -1) { + sprintf(tmp, " | Version Major = [%d]", major); + strcat(str, tmp); + } + + if(minor != -1) { + sprintf(tmp, " | Version Minor = [%d]", minor); + strcat(str, tmp); + } +} + +void fido_attestation_type_cb_list(int att_type, void *user_data) +{ + char *str = (char *) user_data; + + char tmp[1024] = {0,}; + if(att_type != -1) { + sprintf(tmp, " | Attestation Type = [%d]", att_type); + strcat(str, tmp); + } +} + +void ext_cb_list(char *ext, void *user_data) +{ + char *str = (char *) user_data; + + char tmp[1024] = {0,}; + if(ext) { + sprintf(tmp, " | Extension = [%s]", ext); + strcat(str, tmp); + } +} + +static void +__print_authinfo(fido_authenticator_h auth, appdata_s *ad) +{ + char str[2048] = {0,}; + str[0] = '\0'; + strcpy(str, "DISCOVER RESPONSE"); + char tmp[1024] = {0,}; + + char *title = NULL; + fido_authenticator_get_title(auth, &title); + if(title) { + sprintf(tmp, " | Title = [%s]", title); + strcat(str, tmp); + } + + char *aaid = NULL; + fido_authenticator_get_aaid(auth, &aaid); + if(aaid) { + sprintf(tmp, " | AAID = [%s]", aaid); + strcat(str, tmp); + } + + char *description = NULL; + fido_authenticator_get_description(auth, &description); + if(description) { + sprintf(tmp, " | Description = [%s]", description); + strcat(str, tmp); + } + + char *scheme = NULL; + fido_authenticator_get_assertion_scheme(auth, &scheme); + if(scheme) { + sprintf(tmp, " | Scheme = [%s]", scheme); + strcat(str, tmp); + } + + fido_authenticator_foreach_attestation_type(auth, fido_attestation_type_cb_list, str); + + int get_algo = -1; + fido_authenticator_get_algorithm(auth, &get_algo); + if(get_algo != -1) { + sprintf(tmp, " | Algo = [%d]", get_algo); + strcat(str, tmp); + } + + int user_ver = -1; + fido_authenticator_get_verification_method(auth, &user_ver); + if(user_ver != -1) { + sprintf(tmp, " | Verification = [%d]", user_ver); + strcat(str, tmp); + } + + int key_protection = -1; + fido_authenticator_get_verification_method(auth, &key_protection); + if(key_protection != -1) { + sprintf(tmp, " | Key Protection = [%d]", key_protection); + strcat(str, tmp); + } + + int matcher_protection = -1; + fido_authenticator_get_matcher_protection_method(auth, &matcher_protection); + if(matcher_protection != -1) { + sprintf(tmp, " | Matcher Protection = [%d]", matcher_protection); + strcat(str, tmp); + } + + int attachment_hint = -1; + fido_authenticator_get_attachment_hint(auth, &attachment_hint); + if(attachment_hint != -1) { + sprintf(tmp, " | Attachment Hint = [%d]", attachment_hint); + strcat(str, tmp); + } + + int tc_discplay = -1; + fido_authenticator_get_tc_discplay(auth, &tc_discplay); + if(tc_discplay != -1) { + sprintf(tmp, " | Tc Display = [%d]", tc_discplay); + strcat(str, tmp); + } + + char *tc_display_type = NULL; + fido_authenticator_get_tc_display_type(auth, &tc_display_type); + if(tc_display_type) { + sprintf(tmp, " | Tc Display Type = [%s]", tc_display_type); + strcat(str, tmp); + } + + char *icon = NULL; + fido_authenticator_get_icon(auth, &icon); + if(icon) { + sprintf(tmp, " | Icon = [%s]", icon); + strcat(str, tmp); + } + + fido_uaf_authenticator_foreach_extension(auth, ext_cb_list, str); + + create_popup(str, ad); +} + +void auth_list_cb(fido_authenticator_h auth, void *user_data) +{ + appdata_s *ad = user_data; + __print_authinfo(auth, ad); +} + +static void +__print_discovery_data(fido_discovery_data_h discovery_data, appdata_s *ad) +{ + if (discovery_data == NULL) + return; + + int ret = fido_discovery_data_foreach_authenticator(discovery_data, auth_list_cb, ad); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_discovery_data_foreach_authenticator =[%d]", ret); + + fido_discovery_data_destroy(discovery_data); +} + +static void +_fido_authenticator_cb(int tizen_error_code, fido_discovery_data_h discovery_data, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "discover response = [%d]", tizen_error_code); + + if (tizen_error_code == FIDO_ERROR_NONE) { + __print_discovery_data(discovery_data, (appdata_s *) user_data); + } + else { + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); + } +} + +void +start_discover(void *data, Evas_Object *obj, void *event_info) +{ + int ret = fido_foreach_authenticator(_fido_authenticator_cb, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_foreach_authenticator = [%d]", ret); +} + +static void +_policy_cb(int tizen_error_code, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "_policy_cbresponse = [%d]", tizen_error_code); + char str[2048] = {0,}; + str[0] = '\0'; + + strcpy(str, "CHECK POLICY RESPONSE | "); + char *error_string = get_error_code(tizen_error_code); + + sprintf(str, "ret = [%s]", error_string); + create_popup(str, (appdata_s *) user_data); + free(error_string); +} + +void +start_check_policy(void *data, Evas_Object *obj, void *event_info) +{ + int ret = fido_request_is_supported(json_reg, _policy_cb, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_foreach_authenticator = [%d]", ret); +} + +static void +_process_cb(int tizen_error_code, char *uaf_response, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "process response = [%d]", tizen_error_code); + char str[2048] = {0,}; + if (tizen_error_code == 0) { + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "uaf response = %s", uaf_response); + + strcat(str, "uaf response = "); + strcat(str, uaf_response); + create_popup(str, (appdata_s *) user_data); + } + else { + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); + } +} + +void +start_registration(void *data, Evas_Object *obj, void *event_info) +{ + if (json_reg != NULL) { + int ret = fido_request_get_registration_response(json_reg, NULL, _process_cb, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_registration_response = [%d]", ret); + + char str[2048] = {0,}; + str[0] = '\0'; + strcpy(str, "REGISTRATION RESPONSE | "); + char tmp[1024] = {0,}; + sprintf(tmp, "ret = [%d] | ", ret); + strcat(str, tmp); + } +} + +void +start_auth(void *data, Evas_Object *obj, void *event_info) +{ + if (json_auth != NULL) { + int ret = fido_request_get_authentication_response(json_auth, NULL, _process_cb, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_authentication_response = [%d]", ret); + + char str[2048] = {0,}; + str[0] = '\0'; + strcpy(str, "AUTHENTICATION RESPONSE | "); + char tmp[1024] = {0,}; + sprintf(tmp, "ret = [%d] | ", ret); + strcat(str, tmp); + } +} + +static void +_process_dereg_cb(int tizen_error_code, char *uaf_response, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "process response = [%d]", tizen_error_code); + + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); +} + +void +start_de_registration(void *data, Evas_Object *obj, void *event_info) +{ + if (json_reg != NULL) { + int ret = fido_request_get_deregistration_response(json_dereg, NULL, _process_dereg_cb, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_deregistration_response = [%d]", ret); + + char str[2048] = {0,}; + str[0] = '\0'; + strcpy(str, "DE-REGISTRATION RESPONSE | "); + char tmp[1024] = {0,}; + sprintf(tmp, "ret = [%d] | ", ret); + strcat(str, tmp); + } +} + +static void +_process_cb_for_notify_pos(int tizen_error_code, char *uaf_response, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "process response = [%d]", tizen_error_code); + + if (tizen_error_code == 0) { + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "uaf response = %s", uaf_response); + + int ret = fido_request_set_result(FIDO_SERVER_STATUS_CODE_OK, uaf_response); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_set_result =[%d]", ret); + + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); + } + else { + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); + } +} + +static void +_process_cb_for_notify_neg(int tizen_error_code, char *uaf_response, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "process response = [%d]", tizen_error_code); + + if (tizen_error_code == 0) { + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "uaf response = %s", uaf_response); + + int ret = fido_request_set_result(0, uaf_response); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_set_result =[%d]", ret); + + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); + } + else { + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); + } +} + +void +start_notify_pos(void *data, Evas_Object *obj, void *event_info) +{ + if (json_reg != NULL) { + int ret = fido_request_get_registration_response(json_reg, NULL, _process_cb_for_notify_pos, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_registration_response = [%d]", ret); + } +} + +void +start_notify_neg(void *data, Evas_Object *obj, void *event_info) +{ + if (json_reg != NULL) { + int ret = fido_request_get_registration_response(json_reg, NULL, _process_cb_for_notify_neg, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_registration_response = [%d]", ret); + } +} + +static void +win_delete_request_cb(void *data, Evas_Object *obj, void *event_info) +{ + /* To make your application go to background, + Call the elm_win_lower() instead + Evas_Object *win = (Evas_Object *) data; + elm_win_lower(win); */ + ui_app_exit(); +} + +static void +list_selected_cb(void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *it = event_info; + elm_list_item_selected_set(it, EINA_FALSE); +} + +static Eina_Bool +naviframe_pop_cb(void *data, Elm_Object_Item *it) +{ + ui_app_exit(); + return EINA_FALSE; +} + +static void +create_list_view(appdata_s *ad) +{ + Evas_Object *list; + Evas_Object *btn; + Evas_Object *nf = ad->nf; + Elm_Object_Item *nf_it; + + /* List */ + list = elm_list_add(nf); + elm_list_mode_set(list, ELM_LIST_COMPRESS); + evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL); + + /* Main Menu Items Here */ + elm_list_item_append(list, "Discover", NULL, NULL, start_discover, ad); + elm_list_item_append(list, "Check Policy", NULL, NULL, start_check_policy, ad); + elm_list_item_append(list, "Registration", NULL, NULL, start_registration, ad); + elm_list_item_append(list, "Authentication", NULL, NULL, start_auth, ad); + elm_list_item_append(list, "De-Registration", NULL, NULL, start_de_registration, ad); + elm_list_item_append(list, "NotifyResult with Success", NULL, NULL, start_notify_pos, ad); + elm_list_item_append(list, "NotifyResult with Failure", NULL, NULL, start_notify_neg, ad); + + elm_list_go(list); + + /* This button is set for devices which doesn't have H/W back key. */ + btn = elm_button_add(nf); + elm_object_style_set(btn, "naviframe/end_btn/default"); + nf_it = elm_naviframe_item_push(nf, "FIDO Test App", btn, NULL, list, NULL); + elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, ad->win); +} + +static void +create_base_gui(appdata_s *ad) +{ + /* + * Widget Tree + * Window + * - conform + * - layout main + * - naviframe */ + + /* Window */ + ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE); + elm_win_conformant_set(ad->win, EINA_TRUE); + elm_win_autodel_set(ad->win, EINA_TRUE); + + if (elm_win_wm_rotation_supported_get(ad->win)) { + int rots[4] = { 0, 90, 180, 270 }; + elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4); + } + + evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL); + + /* Conformant */ + ad->conform = elm_conformant_add(ad->win); + evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(ad->win, ad->conform); + evas_object_show(ad->conform); + + /* Indicator */ + /* elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW); */ + + /* Base Layout */ + ad->layout = elm_layout_add(ad->conform); + evas_object_size_hint_weight_set(ad->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_layout_theme_set(ad->layout, "layout", "application", "default"); + evas_object_show(ad->layout); + + elm_object_content_set(ad->conform, ad->layout); + + /* Naviframe */ + ad->nf = elm_naviframe_add(ad->layout); + create_list_view(ad); + elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf); + eext_object_event_callback_add(ad->nf, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL); + eext_object_event_callback_add(ad->nf, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL); + + /* Show window after base gui is set up */ + evas_object_show(ad->win); +} + +static bool +app_create(void *data) +{ + /* Hook to take necessary actions before main event loop starts + Initialize UI resources and application's data + If this function returns true, the main loop of application starts + If this function returns false, the application is terminated */ + appdata_s *ad = data; + + elm_app_base_scale_set(1.8); + create_base_gui(ad); + + int ret = fido_uaf_init(); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_uaf_init = [%d]", ret); + + json_reg = __read(_REG_REQ_FILE_NAME); + json_auth = __read(_AUTH_REQ_FILE_NAME); + json_dereg = __read(_DEREG_REQ_FILE_NAME); + + return true; +} + +static void +app_control(app_control_h app_control, void *data) +{ + /* Handle the launch request. */ +} + +static void +app_pause(void *data) +{ + /* Take necessary actions when application becomes invisible. */ +} + +static void +app_resume(void *data) +{ + /* Take necessary actions when application becomes visible. */ +} + +static void +app_terminate(void *data) +{ + /* Release all resources. */ +} + +static void +ui_app_lang_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LANGUAGE_CHANGED*/ + char *locale = NULL; + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale); + elm_language_set(locale); + free(locale); + return; +} + +static void +ui_app_orient_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/ + return; +} + +static void +ui_app_region_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_REGION_FORMAT_CHANGED*/ +} + +static void +ui_app_low_battery(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_BATTERY*/ +} + +static void +ui_app_low_memory(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_MEMORY*/ +} + +int +main(int argc, char *argv[]) +{ + appdata_s ad = {0,}; + int ret = 0; + + ui_app_lifecycle_callback_s event_callback = {0,}; + app_event_handler_h handlers[5] = {NULL, }; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.pause = app_pause; + event_callback.resume = app_resume; + event_callback.app_control = app_control; + + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad); + ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]); + + ret = ui_app_main(argc, argv, &event_callback, &ad); + if (ret != APP_ERROR_NONE) { + dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret); + } + + return ret; +} diff --git a/test/FIDOSample/tizen-manifest.xml b/test/FIDOSample/tizen-manifest.xml new file mode 100644 index 0000000..f26b3da --- /dev/null +++ b/test/FIDOSample/tizen-manifest.xml @@ -0,0 +1,13 @@ + + + + + + fidosample.png + + + http://tizen.org/privilege/account.read + http://tizen.org/privilege/account.write + http://tizen.org/privilege/internet + + diff --git a/test/Fido_Sample_RPM/.cproject b/test/Fido_Sample_RPM/.cproject new file mode 100644 index 0000000..2ca8282 --- /dev/null +++ b/test/Fido_Sample_RPM/.cproject @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Fido_Sample_RPM/.project b/test/Fido_Sample_RPM/.project new file mode 100644 index 0000000..cfe5103 --- /dev/null +++ b/test/Fido_Sample_RPM/.project @@ -0,0 +1,94 @@ + + + FidoSample + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + sbi-make + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/FidoSample} + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + true + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.tizen.nativeplatform.tizenPlatformNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + 1436934632745 + + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-matches-false-false-*/.tpk + + + + diff --git a/test/Fido_Sample_RPM/CMakeLists.txt b/test/Fido_Sample_RPM/CMakeLists.txt new file mode 100644 index 0000000..bffac49 --- /dev/null +++ b/test/Fido_Sample_RPM/CMakeLists.txt @@ -0,0 +1,67 @@ +IF(NOT DEFINED PACKAGE_NAME) + SET(PACKAGE_NAME "org.tizen.FidoSample") +ENDIF(NOT DEFINED PACKAGE_NAME) + +SET(PREFIX "/opt/usr/apps/${PACKAGE_NAME}") + +IF(NOT DEFINED BINDIR) + SET(BINDIR "${PREFIX}/bin") +ENDIF(NOT DEFINED BINDIR) + +IF(NOT DEFINED RESDIR) + SET(RESDIR "${PREFIX}/res") +ENDIF(NOT DEFINED RESDIR) + +IF(NOT DEFINED LOCALEDIR) + SET(LOCALEDIR "${PREFIX}/res/locale") +ENDIF(NOT DEFINED LOCALEDIR) + +IF(NOT DEFINED MANIFESTDIR) + SET(MANIFESTDIR "/opt/share/packages") +ENDIF(NOT DEFINED MANIFESTDIR) + +IF(NOT DEFINED DESKTOP_ICONDIR) + SET(DESKTOP_ICONDIR "/opt/usr/apps/org.tizen.FidoSample/shared/res/") +ENDIF(NOT DEFINED DESKTOP_ICONDIR) + +IF(NOT DEFINED DESKTOP_ICON) + SET(DESKTOP_ICON ${PACKAGE_NAME}.png) +ENDIF(NOT DEFINED DESKTOP_ICON) + +SET(TEST_SRCS + src/main.c +) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test/Fido_Sample_RPM/include) + +ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE_NAME}\"") + +INCLUDE(FindPkgConfig) +pkg_check_modules(TEST_PKGS REQUIRED + elementary + efl-extension + capi-appfw-application + capi-system-system-settings + dlog + json-glib-1.0 + glib-2.0 + gio-unix-2.0) + +FOREACH(flag ${TEST_PKGS_CFLAGS}) + SET(EXTRA_CFLGAS "${EXTRA_CFLGAS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE ${EXTRA_CFLGAS}") +ADD_EXECUTABLE(${PACKAGE_NAME} ${TEST_SRCS}) +TARGET_LINK_LIBRARIES(${PACKAGE_NAME} ${TEST_PKGS_LDFLAGS} ) +TARGET_LINK_LIBRARIES(${PACKAGE_NAME} fido-client) +CONFIGURE_FILE(${PACKAGE_NAME}.xml.in ${PACKAGE_NAME}.xml) + +INSTALL(TARGETS ${PACKAGE_NAME} DESTINATION ${BINDIR}) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/test/Fido_Sample_RPM/res/reg_req.json DESTINATION ${RESDIR}) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/test/Fido_Sample_RPM/res/auth_req.json DESTINATION ${RESDIR}) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/test/Fido_Sample_RPM/res/dereg_req.json DESTINATION ${RESDIR}) +INSTALL(FILES ${PACKAGE_NAME}.xml DESTINATION ${MANIFESTDIR}) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/test/Fido_Sample_RPM/${DESKTOP_ICON} DESTINATION ${DESKTOP_ICONDIR}) diff --git a/test/Fido_Sample_RPM/include/main.h b/test/Fido_Sample_RPM/include/main.h new file mode 100644 index 0000000..6514cba --- /dev/null +++ b/test/Fido_Sample_RPM/include/main.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "org.tizen.Fidosample" + +#define KEY_END "XF86Stop" + +#if !defined(PACKAGE) +#define PACKAGE "org.tizen.fidosample" +#endif + +#define ELM_DEMO_EDJ "/opt/usr/apps/org.tizen.fidosample/res/ui_controls.edj" +#define ICON_DIR "/opt/usr/apps/org.tizen.fidosample/res/images" + + +typedef struct appdata { + Evas_Object *win; + Evas_Object *conform; + Evas_Object *layout; + Evas_Object *nf; + Evas_Object *datetime; + Evas_Object *popup; + Evas_Object *button; + struct tm saved_time; +} appdata_s; + +void start_discover(void *data, Evas_Object *obj, void *event_info); +void start_check_policy(void *data, Evas_Object *obj, void *event_info); +void start_registration(void *data, Evas_Object *obj, void *event_info); +void start_auth(void *data, Evas_Object *obj, void *event_info); +void start_de_registration(void *data, Evas_Object *obj, void *event_info); diff --git a/test/Fido_Sample_RPM/org.tizen.FidoSample.png b/test/Fido_Sample_RPM/org.tizen.FidoSample.png new file mode 100644 index 0000000..9765b1b Binary files /dev/null and b/test/Fido_Sample_RPM/org.tizen.FidoSample.png differ diff --git a/test/Fido_Sample_RPM/org.tizen.FidoSample.xml.in b/test/Fido_Sample_RPM/org.tizen.FidoSample.xml.in new file mode 100644 index 0000000..0e878d0 --- /dev/null +++ b/test/Fido_Sample_RPM/org.tizen.FidoSample.xml.in @@ -0,0 +1,13 @@ + + + + + + org.tizen.FidoSample.png + + + http://tizen.org/privilege/account.read + http://tizen.org/privilege/account.write + http://tizen.org/privilege/internet + + diff --git a/test/Fido_Sample_RPM/po/CMakeLists.txt b/test/Fido_Sample_RPM/po/CMakeLists.txt new file mode 100644 index 0000000..cd07287 --- /dev/null +++ b/test/Fido_Sample_RPM/po/CMakeLists.txt @@ -0,0 +1,37 @@ +# for i18n + +SET(POFILES de_DE.po + el_GR.po + en.po + es_ES.po + fr_FR.po + it_IT.po + ja_JP.po + ko_KR.po + nl_NL.po + pt_PT.po + ru_RU.po + tr_TR.po + zh_CN.po + zh_HK.po + zh_TW.po) +SET(MSGFMT "/usr/bin/msgfmt") + +FOREACH(pofile ${POFILES}) + SET(pofile ${CMAKE_CURRENT_SOURCE_DIR}/${pofile}) + MESSAGE("PO: ${pofile}") + GET_FILENAME_COMPONENT(absPofile ${pofile} ABSOLUTE) + GET_FILENAME_COMPONENT(lang ${absPofile} NAME_WE) + SET(moFile ${CMAKE_CURRENT_BINARY_DIR}/${lang}.mo) + ADD_CUSTOM_COMMAND( + OUTPUT ${moFile} + COMMAND ${MSGFMT} -o ${moFile} ${absPofile} + DEPENDS ${absPofile} + ) + INSTALL(FILES ${moFile} + DESTINATION ${LOCALEDIR}/${lang}/LC_MESSAGES RENAME ${PROJECT_NAME}.mo) + SET(moFiles ${moFiles} ${moFile}) +ENDFOREACH(pofile) + +MESSAGE(".mo files: ${moFiles}") +ADD_CUSTOM_TARGET(po ALL DEPENDS ${moFiles}) diff --git a/test/Fido_Sample_RPM/po/POTFILES.in b/test/Fido_Sample_RPM/po/POTFILES.in new file mode 100644 index 0000000..5dda005 --- /dev/null +++ b/test/Fido_Sample_RPM/po/POTFILES.in @@ -0,0 +1,2 @@ +# List of source files containing translatable strings. +src/main.c diff --git a/test/Fido_Sample_RPM/po/de_DE.po b/test/Fido_Sample_RPM/po/de_DE.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/de_DE.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/el_GR.po b/test/Fido_Sample_RPM/po/el_GR.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/el_GR.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/en.po b/test/Fido_Sample_RPM/po/en.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/en.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/es_ES.po b/test/Fido_Sample_RPM/po/es_ES.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/es_ES.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/fr_FR.po b/test/Fido_Sample_RPM/po/fr_FR.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/fr_FR.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/hello-efl.pot b/test/Fido_Sample_RPM/po/hello-efl.pot new file mode 100644 index 0000000..0f2e228 --- /dev/null +++ b/test/Fido_Sample_RPM/po/hello-efl.pot @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/it_IT.po b/test/Fido_Sample_RPM/po/it_IT.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/it_IT.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/ja_JP.po b/test/Fido_Sample_RPM/po/ja_JP.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/ja_JP.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/ko_KR.po b/test/Fido_Sample_RPM/po/ko_KR.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/ko_KR.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/nl_NL.po b/test/Fido_Sample_RPM/po/nl_NL.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/nl_NL.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/pt_PT.po b/test/Fido_Sample_RPM/po/pt_PT.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/pt_PT.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/ru_RU.po b/test/Fido_Sample_RPM/po/ru_RU.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/ru_RU.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/tr_TR.po b/test/Fido_Sample_RPM/po/tr_TR.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/tr_TR.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/update-po.sh b/test/Fido_Sample_RPM/po/update-po.sh new file mode 100644 index 0000000..665444f --- /dev/null +++ b/test/Fido_Sample_RPM/po/update-po.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +APPNAME=hello-efl +SRCROOT=.. +POTFILES=POTFILES.in + +ALL_LINGUAS="de_DE el_GR en es_ES fr_FR it_IT ja_JP ko_KR nl_NL pt_PT ru_RU tr_TR zh_CN zh_HK zh_TW" + +XGETTEXT=/usr/bin/xgettext +MSGMERGE=/usr/bin/msgmerge + +echo -n "Make ${APPNAME}.pot " +if [ ! -e $POTFILES ] ; then + echo "$POTFILES not found" + exit 1 +fi + +$XGETTEXT --default-domain=${APPNAME} --directory=${SRCROOT} \ + --add-comments --keyword=_ --keyword=N_ --files-from=$POTFILES +if [ $? -ne 0 ]; then + echo "xgettext error" + exit 1 +fi + +if [ ! -f ${APPNAME}.po ]; then + echo "No such file: ${APPNAME}.po" + exit 1 +fi + +rm -f ${APPNAME}.pot && mv ${APPNAME}.po ${APPNAME}.pot +echo "done" + +for LANG in $ALL_LINGUAS; do + echo "$LANG : " + + if [ ! -e $LANG.po ] ; then + sed 's/CHARSET/UTF-8/g' ${APPNAME}.pot > ${LANG}.po + echo "${LANG}.po created" + else + if $MSGMERGE ${LANG}.po ${APPNAME}.pot -o ${LANG}.new.po ; then + if cmp ${LANG}.po ${LANG}.new.po > /dev/null 2>&1; then + rm -f ${LANG}.new.po + else + if mv -f ${LANG}.new.po ${LANG}.po; then + echo "" + else + echo "msgmerge for $LANG.po failed: cannot move $LANG.new.po to $LANG.po" 1>&2 + rm -f ${LANG}.new.po + exit 1 + fi + fi + else + echo "msgmerge for $LANG failed!" + rm -f ${LANG}.new.po + fi + fi + echo "" +done + diff --git a/test/Fido_Sample_RPM/po/zh_CN.po b/test/Fido_Sample_RPM/po/zh_CN.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/zh_CN.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/zh_HK.po b/test/Fido_Sample_RPM/po/zh_HK.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/zh_HK.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/po/zh_TW.po b/test/Fido_Sample_RPM/po/zh_TW.po new file mode 100644 index 0000000..f90724d --- /dev/null +++ b/test/Fido_Sample_RPM/po/zh_TW.po @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-04-09 09:44+0900\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/main.c:50 +msgid "Hello EFL" +msgstr "" diff --git a/test/Fido_Sample_RPM/res/auth_req.json b/test/Fido_Sample_RPM/res/auth_req.json new file mode 100644 index 0000000..4ea65f4 --- /dev/null +++ b/test/Fido_Sample_RPM/res/auth_req.json @@ -0,0 +1,50 @@ +[ + { + "header": { + "upv": { + "major": 1, + "minor": 0 + }, + "op": "Auth", + "appID": "org.tizen.FidoSample", + "serverData": "emKubKMS8RxYOth7J8enT_x7dQWBaO1CiC0fGmSEhX56kq2RYo1LRpwvfHlzYRI3p9Ay-l4zJcV3lX6rQ0CYNWi5nNDabClFm3k0pPj0kX5V-db9ejN_05y2J6wqztSD" + }, + "challenge": "1AM2yZY4-9SG4Ns7-hMdB8IV_FTDKFFiUqNJNVbsVoo", + "transaction": [ + { + "contentType": "text/plain", + "content": "VHJhbnNhY3Rpb24gQ29udGVudCBmb3IgVGVzdC4", + "tcDisplayPNGCharacteristics": [ + { + "width": 320, + "height": 240, + "bitDepth": 16, + "colorType": 2, + "compression": 0, + "filter": 0, + "interlace": 0 + } + ] + } + ], + "policy": { + "accepted": [ + [ + { + "aaid": [ + "0000#C001" + ] + } + ], + [ + { + "aaid": [ + "53EC#3101" + ] + } + ] + ] + } + } +] + diff --git a/test/Fido_Sample_RPM/res/dereg_req.json b/test/Fido_Sample_RPM/res/dereg_req.json new file mode 100644 index 0000000..9ab6684 --- /dev/null +++ b/test/Fido_Sample_RPM/res/dereg_req.json @@ -0,0 +1,18 @@ +[ + { + "header": { + "upv": { + "major": "1", + "minor": "0" + }, + "op": "Dereg", + "appID": "org.tizen.FidoSample" + }, + "authenticators": [ + { + "aaid": "53EC#3101", + "keyID": "uWrbo_8JI1HmPESrNAStTVV8ZbBrzLsf_kZu1QKX2YY" + } + ] + } +] diff --git a/test/Fido_Sample_RPM/res/reg_req.json b/test/Fido_Sample_RPM/res/reg_req.json new file mode 100644 index 0000000..c07b6d1 --- /dev/null +++ b/test/Fido_Sample_RPM/res/reg_req.json @@ -0,0 +1,33 @@ +[ + { + "header": { + "upv": { + "major": 1, + "minor": 0 + }, +"op":"Reg", +"appID":"org.tizen.FidoSample", + "serverData": "nwV8EPqS5raZdAgH3GD9Z-ytCA9MkiiWaCsr1GHHNJ2yUh3HaV1HHxd4Z67FefJOD5sQYZvipfg5BavhdWPMecD2SH39aJixoXN9ZaNwRlcftJe9WbtPNDC9q5V9WX7Z5jCwkAwehcI" + }, + "challenge": "9pIcUwwrY5eD9o3OwfhkeHLnoIl0vaeJUbxSHMe_XgE", +"username":"ryan", + "policy": { + "accepted": [ + [ + { + "aaid": [ + "0000#C001" + ] + } + ], + [ + { + "aaid": [ + "53EC#3101" + ] + } + ] + ] + } + } +] diff --git a/test/Fido_Sample_RPM/src/main.c b/test/Fido_Sample_RPM/src/main.c new file mode 100755 index 0000000..c0f2a83 --- /dev/null +++ b/test/Fido_Sample_RPM/src/main.c @@ -0,0 +1,638 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "main.h" +#include "fido.h" +#include + +#define _REG_REQ_FILE_NAME "/opt/usr/apps/org.tizen.FidoSample/res/reg_req.json" +#define _AUTH_REQ_FILE_NAME "/opt/usr/apps/org.tizen.FidoSample/res/auth_req.json" +#define _DEREG_REQ_FILE_NAME "/opt/usr/apps/org.tizen.FidoSample/res/dereg_req.json" + +static char *json_reg = NULL; +static char *json_auth = NULL; +static char *json_dereg = NULL; + +static char* +__read(const char *file_name) +{ + FILE *file = fopen(file_name, "rb"); + if (file == NULL) + return NULL; + + fseek(file, 0, SEEK_END); + long size = ftell(file); + if (size <= 0) { + fclose(file); + return NULL; + } + + fseek(file, 0, SEEK_SET); + + char *json = calloc(1, size + 1); + int num_bytes = fread(json, size, 1, file); + if (num_bytes <= 0) { + free(json); + fclose(file); + return NULL; + } + + json[size] = 0; + + fclose(file); + + return json; + +} + +static void _response_cb(void *data, Evas_Object *obj, void *event_info) +{ + evas_object_del(data); +} + +static void create_popup(char *popup_str, appdata_s *ad) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido %s", popup_str); + + Evas_Object *popup = elm_popup_add(ad->win); + Evas_Object *btn; + + elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(popup, popup_str); + + btn = elm_button_add(popup); + elm_object_style_set(btn, "popup"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_text_set(btn, "OK"); + elm_object_part_content_set(popup, "button1", btn); + eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, NULL); + evas_object_smart_callback_add(btn, "clicked", _response_cb, popup); + evas_object_show(popup); + + return; +} + +char *get_error_code(fido_error_e error_code) +{ + + char *error_str = calloc(1,128); + + if(error_code == FIDO_ERROR_NONE) + strcpy(error_str, "SUCCESS"); + else if (error_code == FIDO_ERROR_OUT_OF_MEMORY) + strcpy(error_str, "FIDO_ERROR_OUT_OF_MEMORY"); + else if (error_code == FIDO_ERROR_INVALID_PARAMETER) + strcpy(error_str, "FIDO_ERROR_INVALID_PARAMETER"); + else if (error_code == FIDO_ERROR_NO_DATA) + strcpy(error_str, "FIDO_ERROR_NO_DATA"); + else if (error_code == FIDO_ERROR_PERMISSION_DENIED) + strcpy(error_str, "FIDO_ERROR_PERMISSION_DENIED"); + else if (error_code == FIDO_ERROR_NOT_SUPPORTED) + strcpy(error_str, "FIDO_ERROR_NOT_SUPPORTED"); + else if (error_code == FIDO_ERROR_USER_ACTION_IN_PROGRESS) + strcpy(error_str, "FIDO_ERROR_USER_ACTION_IN_PROGRESS"); + else if (error_code == FIDO_ERROR_USER_CANCELLED) + strcpy(error_str, "FIDO_ERROR_USER_CANCELLED"); + else if (error_code == FIDO_ERROR_UNSUPPORTED_VERSION) + strcpy(error_str, "FIDO_ERROR_UNSUPPORTED_VERSION"); + else if (error_code == FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR) + strcpy(error_str, "FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR"); + else if (error_code == FIDO_ERROR_PROTOCOL_ERROR) + strcpy(error_str, "FIDO_ERROR_PROTOCOL_ERROR"); + else if (error_code == FIDO_ERROR_UNTRUSTED_FACET_ID) + strcpy(error_str, "FIDO_ERROR_UNTRUSTED_FACET_ID"); + else + strcpy(error_str, "FIDO_ERROR_UNKNOWN"); + return error_str; +} + +static void +__show_error(int tizen_error_code, appdata_s *app_data) +{ + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, app_data); + free(error_string); +} + +void fido_attestation_type_cb_list(fido_auth_attestation_type_e att_type, void *user_data) +{ + char *str = (char *) user_data; + + char tmp[1024] = {0,}; + if(att_type != -1) { + sprintf(tmp, " | Attestation Type = [%d]", att_type); + strcat(str, tmp); + } +} + +static void +__print_authinfo(const fido_authenticator_h auth, appdata_s *ad) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido __print_authinfo"); + + char str[5000] = {0,}; + str[0] = '\0'; + strcpy(str, "DISCOVER RESPONSE"); + char tmp[1024] = {0,}; + + char *title = NULL; + fido_authenticator_get_title(auth, &title); + if(title) { + sprintf(tmp, " | Title = [%s]", title); + strcat(str, tmp); + } + free(title); + + char *aaid = NULL; + fido_authenticator_get_aaid(auth, &aaid); + if(aaid) { + sprintf(tmp, " | AAID = [%s]", aaid); + strcat(str, tmp); + } + free(aaid); + + char *description = NULL; + fido_authenticator_get_description(auth, &description); + if(description) { + sprintf(tmp, " | Description = [%s]", description); + strcat(str, tmp); + } + free(description); + + char *scheme = NULL; + fido_authenticator_get_assertion_scheme(auth, &scheme); + if(scheme) { + sprintf(tmp, " | Scheme = [%s]", scheme); + strcat(str, tmp); + } + free(scheme); + + fido_authenticator_foreach_attestation_type(auth, fido_attestation_type_cb_list, str); + + fido_auth_algo_e get_algo = -1; + fido_authenticator_get_algorithm(auth, &get_algo); + if(get_algo != -1) { + sprintf(tmp, " | Algo = [%d]", get_algo); + strcat(str, tmp); + } + + fido_auth_user_verify_type_e user_ver = -1; + fido_authenticator_get_verification_method(auth, &user_ver); + if(user_ver != -1) { + sprintf(tmp, " | Verification = [%d]", user_ver); + strcat(str, tmp); + } + + fido_auth_key_protection_type_e key_protection = -1; + fido_authenticator_get_key_protection_method(auth, &key_protection); + if(key_protection != -1) { + sprintf(tmp, " | Key Protection = [%d]", key_protection); + strcat(str, tmp); + } + + fido_auth_matcher_protection_type_e matcher_protection = -1; + fido_authenticator_get_matcher_protection_method(auth, &matcher_protection); + if(matcher_protection != -1) { + sprintf(tmp, " | Matcher Protection = [%d]", matcher_protection); + strcat(str, tmp); + } + + fido_auth_attachment_hint_e attachment_hint = -1; + fido_authenticator_get_attachment_hint(auth, &attachment_hint); + if(attachment_hint != -1) { + sprintf(tmp, " | Attachment Hint = [%d]", attachment_hint); + strcat(str, tmp); + } + + fido_auth_tc_display_type_e tc_discplay = -1; + fido_authenticator_get_tc_discplay(auth, &tc_discplay); + if(tc_discplay != -1) { + sprintf(tmp, " | Tc Display = [%d]", tc_discplay); + strcat(str, tmp); + } + + char *tc_display_type = NULL; + fido_authenticator_get_tc_display_type(auth, &tc_display_type); + if(tc_display_type) { + sprintf(tmp, " | Tc Display Type = [%s]", tc_display_type); + strcat(str, tmp); + } + free(tc_display_type); + + char *icon = NULL; + fido_authenticator_get_icon(auth, &icon); + if(icon) { + sprintf(tmp, " | Icon = [%s]", icon); + strcat(str, tmp); + } + free(icon); + + create_popup(str, ad); +} + +static void +auth_list_cb(const fido_authenticator_h auth, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido auth_list_cb"); + + appdata_s *ad = user_data; + __print_authinfo(auth, ad); +} + +void +start_discover(void *data, Evas_Object *obj, void *event_info) +{ + int ret = fido_foreach_authenticator(auth_list_cb, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_get_available_authenticators = [%d]", ret); + + if (ret != FIDO_ERROR_NONE) + __show_error(ret, (appdata_s *)data); + +} + +void +start_check_policy(void *data, Evas_Object *obj, void *event_info) +{ + bool is_supported = false; + int ret = fido_uaf_is_supported(json_reg, &is_supported); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_uaf_is_supported = [%d]", ret); + + char str[2048] = {0,}; + str[0] = '\0'; + + strcpy(str, "CHECK POLICY RESPONSE | "); + + if (ret != FIDO_ERROR_NONE) { + char *error_string = get_error_code(ret); + + sprintf(str, "[%s]", error_string); + create_popup(str, (appdata_s *) data); + free(error_string); + } + else { + if (is_supported == true) + sprintf(str, "TRUE"); + else + sprintf(str, "FALSE"); + + create_popup(str, (appdata_s *) data); + } +} + +static void +_process_cb(fido_error_e tizen_error_code, const char *uaf_response, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "process response = [%d]", tizen_error_code); + + if (tizen_error_code == 0 && uaf_response != NULL) { + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "uaf response = %s", uaf_response); + + const int max_popup_str_len = strlen(uaf_response) + 500; + char *popup_str = calloc(1, max_popup_str_len); + + snprintf(popup_str, max_popup_str_len - 1, "UAF Response =%s", uaf_response); + + create_popup(popup_str, (appdata_s *) user_data); + free(popup_str); + } + else { + __show_error(tizen_error_code, (appdata_s *)user_data); + } +} + +void +start_registration(void *data, Evas_Object *obj, void *event_info) +{ + if (json_reg != NULL) { + int ret = fido_uaf_get_response_message(json_reg, NULL, _process_cb, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_registration_response = [%d]", ret); + if (ret != FIDO_ERROR_NONE) + __show_error(ret, (appdata_s *)data); + } +} + +void +start_auth(void *data, Evas_Object *obj, void *event_info) +{ + if (json_auth != NULL) { + int ret = fido_uaf_get_response_message(json_auth, NULL, _process_cb, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_authentication_response = [%d]", ret); + + if (ret != FIDO_ERROR_NONE) + __show_error(ret, (appdata_s *)data); + } +} + +static void +_process_dereg_cb(fido_error_e tizen_error_code, const char *uaf_response, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "process response = [%d]", tizen_error_code); + + if (uaf_response) + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "uaf_response = [%s]", uaf_response); + else + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "uaf_response = [NULL]"); + + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); +} + +void +start_de_registration(void *data, Evas_Object *obj, void *event_info) +{ + if (json_reg != NULL) { + int ret = fido_uaf_get_response_message(json_dereg, NULL, _process_dereg_cb, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_deregistration_response = [%d]", ret); + + if (ret != FIDO_ERROR_NONE) + __show_error(ret, (appdata_s *)data); + } +} + +static void +_process_cb_for_notify_pos(fido_error_e tizen_error_code, const char *uaf_response, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "process response = [%d]", tizen_error_code); + + if (tizen_error_code == 0) { + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "uaf response = %s", uaf_response); + + int ret = fido_uaf_set_server_result(FIDO_SERVER_STATUS_CODE_OK, uaf_response); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_uaf_set_server_result =[%d]", ret); + + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); + } + else { + __show_error(tizen_error_code, (appdata_s *)user_data); + } +} + +static void +_process_cb_for_notify_neg(fido_error_e tizen_error_code, const char *uaf_response, void *user_data) +{ + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "process response = [%d]", tizen_error_code); + + if (tizen_error_code == 0) { + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "uaf response = %s", uaf_response); + + int ret = fido_uaf_set_server_result(0, uaf_response); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_uaf_set_server_result =[%d]", ret); + + char *error_string = get_error_code(tizen_error_code); + create_popup(error_string, (appdata_s *) user_data); + free(error_string); + } + else { + __show_error(tizen_error_code, (appdata_s *)user_data); + } +} + +void +start_notify_pos(void *data, Evas_Object *obj, void *event_info) +{ + if (json_reg != NULL) { + int ret = fido_uaf_get_response_message(json_reg, NULL, _process_cb_for_notify_pos, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_registration_response = [%d]", ret); + } +} + +void +start_notify_neg(void *data, Evas_Object *obj, void *event_info) +{ + if (json_reg != NULL) { + int ret = fido_uaf_get_response_message(json_reg, NULL, _process_cb_for_notify_neg, data); + dlog_print(DLOG_INFO, "org.tizen.Fidosample", "fido_request_get_registration_response = [%d]", ret); + } +} + +static void +win_delete_request_cb(void *data, Evas_Object *obj, void *event_info) +{ + /* To make your application go to background, + Call the elm_win_lower() instead + Evas_Object *win = (Evas_Object *) data; + elm_win_lower(win); */ + ui_app_exit(); +} + +static void +list_selected_cb(void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *it = event_info; + elm_list_item_selected_set(it, EINA_FALSE); +} + +static Eina_Bool +naviframe_pop_cb(void *data, Elm_Object_Item *it) +{ + ui_app_exit(); + return EINA_FALSE; +} + +static void +create_list_view(appdata_s *ad) +{ + Evas_Object *list; + Evas_Object *btn; + Evas_Object *nf = ad->nf; + Elm_Object_Item *nf_it; + + /* List */ + list = elm_list_add(nf); + elm_list_mode_set(list, ELM_LIST_COMPRESS); + evas_object_smart_callback_add(list, "selected", list_selected_cb, NULL); + + /* Main Menu Items Here */ + elm_list_item_append(list, "Find Authenticator", NULL, NULL, start_discover, ad); + elm_list_item_append(list, "Check UAF Message Supported", NULL, NULL, start_check_policy, ad); + elm_list_item_append(list, "Registration", NULL, NULL, start_registration, ad); + elm_list_item_append(list, "Authentication", NULL, NULL, start_auth, ad); + elm_list_item_append(list, "De-Registration", NULL, NULL, start_de_registration, ad); + elm_list_item_append(list, "Set Server Result with Success", NULL, NULL, start_notify_pos, ad); + elm_list_item_append(list, "Set Server Result with Failure", NULL, NULL, start_notify_neg, ad); + + elm_list_go(list); + + /* This button is set for devices which doesn't have H/W back key. */ + btn = elm_button_add(nf); + elm_object_style_set(btn, "naviframe/end_btn/default"); + nf_it = elm_naviframe_item_push(nf, "FIDO Test App", btn, NULL, list, NULL); + elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, ad->win); +} + +static void +create_base_gui(appdata_s *ad) +{ + /* + * Widget Tree + * Window + * - conform + * - layout main + * - naviframe */ + + /* Window */ + ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE); + elm_win_conformant_set(ad->win, EINA_TRUE); + elm_win_autodel_set(ad->win, EINA_TRUE); + + if (elm_win_wm_rotation_supported_get(ad->win)) { + int rots[4] = { 0, 90, 180, 270 }; + elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4); + } + + evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL); + + /* Conformant */ + ad->conform = elm_conformant_add(ad->win); + evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(ad->win, ad->conform); + evas_object_show(ad->conform); + + /* Indicator */ + /* elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW); */ + + /* Base Layout */ + ad->layout = elm_layout_add(ad->conform); + evas_object_size_hint_weight_set(ad->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_layout_theme_set(ad->layout, "layout", "application", "default"); + evas_object_show(ad->layout); + + elm_object_content_set(ad->conform, ad->layout); + + /* Naviframe */ + ad->nf = elm_naviframe_add(ad->layout); + create_list_view(ad); + elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf); + eext_object_event_callback_add(ad->nf, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL); + eext_object_event_callback_add(ad->nf, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL); + + /* Show window after base gui is set up */ + evas_object_show(ad->win); +} + +static bool +app_create(void *data) +{ + /* Hook to take necessary actions before main event loop starts + Initialize UI resources and application's data + If this function returns true, the main loop of application starts + If this function returns false, the application is terminated */ + appdata_s *ad = data; + + elm_app_base_scale_set(1.8); + create_base_gui(ad); + + json_reg = __read(_REG_REQ_FILE_NAME); + json_auth = __read(_AUTH_REQ_FILE_NAME); + json_dereg = __read(_DEREG_REQ_FILE_NAME); + + return true; +} + +static void +app_control(app_control_h app_control, void *data) +{ + /* Handle the launch request. */ +} + +static void +app_pause(void *data) +{ + /* Take necessary actions when application becomes invisible. */ +} + +static void +app_resume(void *data) +{ + /* Take necessary actions when application becomes visible. */ +} + +static void +app_terminate(void *data) +{ + /* Release all resources. */ +} + +static void +ui_app_lang_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LANGUAGE_CHANGED*/ + char *locale = NULL; + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale); + elm_language_set(locale); + free(locale); + return; +} + +static void +ui_app_orient_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/ + return; +} + +static void +ui_app_region_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_REGION_FORMAT_CHANGED*/ +} + +static void +ui_app_low_battery(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_BATTERY*/ +} + +static void +ui_app_low_memory(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_MEMORY*/ +} + +int +main(int argc, char *argv[]) +{ + appdata_s ad = {0,}; + int ret = 0; + + ui_app_lifecycle_callback_s event_callback = {0,}; + app_event_handler_h handlers[5] = {NULL, }; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.pause = app_pause; + event_callback.resume = app_resume; + event_callback.app_control = app_control; + + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad); + ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]); + + ret = ui_app_main(argc, argv, &event_callback, &ad); + if (ret != APP_ERROR_NONE) { + dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret); + } + + return ret; +} diff --git a/test/shell_tc/CMakeLists.txt b/test/shell_tc/CMakeLists.txt new file mode 100644 index 0000000..63dd85e --- /dev/null +++ b/test/shell_tc/CMakeLists.txt @@ -0,0 +1,33 @@ +SET(FIDO_SHELL_TC fido-shell-tc) + +INCLUDE(FindPkgConfig) +pkg_check_modules(FIDO_SHELL_TC_PKGS REQUIRED + dlog + glib-2.0 + gio-unix-2.0 + capi-base-common +) + +FOREACH(flag ${FIDO_SHELL_TC_PKGS_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/test/shell_tc) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) + + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror -Wno-unused-result") +SET(CMAKE_LDFLAGS "-Wl,-zdefs") + +SET(FIDO_SHELL_TC_SRCS + fido_shell_tc_util.c + fido_shell_tc.c +) + +ADD_EXECUTABLE(${FIDO_SHELL_TC} ${FIDO_SHELL_TC_SRCS}) + +TARGET_LINK_LIBRARIES(${FIDO_SHELL_TC} ${FIDO_SHELL_TC_LDFLAGS}) +TARGET_LINK_LIBRARIES(${FIDO_SHELL_TC} fido-client) + +INSTALL(TARGETS ${FIDO_SHELL_TC} DESTINATION /opt/usr/devel/fido/tc) diff --git a/test/shell_tc/fido_shell_tc.c b/test/shell_tc/fido_shell_tc.c new file mode 100644 index 0000000..f5e33e8 --- /dev/null +++ b/test/shell_tc/fido_shell_tc.c @@ -0,0 +1,421 @@ + +#include "fido_shell_tc_util.h" +#include "fido.h" + +#include +#include +#include + +static char *json_reg = "[ { \"header\": { \"upv\": { \"major\": 1, \"minor\": 0 },\"op\":\"Reg\", \"serverData\": \"nwV8EPqS5raZdAgH3GD9Z-ytCA9MkiiWaCsr1GHHNJ2yUh3HaV1HHxd4Z67FefJOD5sQYZvipfg5BavhdWPMecD2SH39aJixoXN9ZaNwRlcftJe9WbtPNDC9q5V9WX7Z5jCwkAwehcI\" }, \"challenge\": \"9pIcUwwrY5eD9o3OwfhkeHLnoIl0vaeJUbxSHMe_XgE\", \"username\":\"ryan\", \"policy\": { \"accepted\": [ [ { \"aaid\": [ \"0001#8001\" ] } ], [ { \"aaid\": [ \"53EC#3101\" ] } ] ] } } ]"; +static char *json_auth = "[ { \"header\": { \"upv\": { \"major\": 1, \"minor\": 0 }, \"op\": \"Auth\", \"serverData\": \"emKubKMS8RxYOth7J8enT_x7dQWBaO1CiC0fGmSEhX56kq2RYo1LRpwvfHlzYRI3p9Ay-l4zJcV3lX6rQ0CYNWi5nNDabClFm3k0pPj0kX5V-db9ejN_05y2J6wqztSD\" }, \"challenge\": \"1AM2yZY4-9SG4Ns7-hMdB8IV_FTDKFFiUqNJNVbsVoo\", \"transaction\": [ { \"contentType\": \"text/plain\", \"content\": \"VHJhbnNhY3Rpb24gQ29udGVudCBmb3IgVGVzdC4\", \"tcDisplayPNGCharacteristics\": [ { \"width\": 320, \"height\": 240, \"bitDepth\": 16, \"colorType\": 2, \"compression\": 0, \"filter\": 0, \"interlace\": 0 } ] } ], \"policy\": { \"accepted\": [ [ { \"aaid\": [ \"0001#8001\" ] } ], [ { \"aaid\": [ \"53EC#3101\" ] } ] ] } } ]"; +static char *json_dereg = "[ { \"header\": { \"upv\": { \"major\": \"1\", \"minor\": \"0\" }, \"op\": \"Dereg\" }, \"authenticators\": [ { \"aaid\": \"0001#8001\", \"keyID\": \"uWrbo_8JI1HmPESrNAStTVV8ZbBrzLsf_kZu1QKX2YY\" } ] } ]"; + +void get_user_choice(void); + +static char * +__get_error_code(fido_error_e error_code) +{ + + char *error_str = calloc(1, 128); + + if(error_code == FIDO_ERROR_NONE) + strcpy(error_str, "SUCCESS"); + else if (error_code == FIDO_ERROR_OUT_OF_MEMORY) + strcpy(error_str, "FIDO_ERROR_OUT_OF_MEMORY"); + else if (error_code == FIDO_ERROR_INVALID_PARAMETER) + strcpy(error_str, "FIDO_ERROR_INVALID_PARAMETER"); + else if (error_code == FIDO_ERROR_NO_DATA) + strcpy(error_str, "FIDO_ERROR_NO_DATA"); + else if (error_code == FIDO_ERROR_PERMISSION_DENIED) + strcpy(error_str, "FIDO_ERROR_PERMISSION_DENIED"); + else if (error_code == FIDO_ERROR_NOT_SUPPORTED) + strcpy(error_str, "FIDO_ERROR_NOT_SUPPORTED"); + else if (error_code == FIDO_ERROR_USER_ACTION_IN_PROGRESS) + strcpy(error_str, "FIDO_ERROR_USER_ACTION_IN_PROGRESS"); + else if (error_code == FIDO_ERROR_USER_CANCELLED) + strcpy(error_str, "FIDO_ERROR_USER_CANCELLED"); + else if (error_code == FIDO_ERROR_UNSUPPORTED_VERSION) + strcpy(error_str, "FIDO_ERROR_UNSUPPORTED_VERSION"); + else if (error_code == FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR) + strcpy(error_str, "FIDO_ERROR_NO_SUITABLE_AUTHENTICATOR"); + else if (error_code == FIDO_ERROR_PROTOCOL_ERROR) + strcpy(error_str, "FIDO_ERROR_PROTOCOL_ERROR"); + else if (error_code == FIDO_ERROR_UNTRUSTED_FACET_ID) + strcpy(error_str, "FIDO_ERROR_UNTRUSTED_FACET_ID"); + else + strcpy(error_str, "FIDO_ERROR_UNKNOWN"); + return error_str; +} + +static void +__show_error(int tizen_error_code) +{ + char *error_string = __get_error_code(tizen_error_code); + printf("%s\n", error_string); + fflush(stdout); + free(error_string); +} + +static void +__process_cb(fido_error_e tizen_error_code, const char *uaf_response, void *user_data) +{ + if (tizen_error_code == 0 && uaf_response != NULL) { + + const int max_str_len = strlen(uaf_response) + 500; + char *display_str = calloc(1, max_str_len); + + snprintf(display_str, max_str_len - 1, "UAF Response =%s", uaf_response); + + printf("%s\n", uaf_response); + free(display_str); + } + else { + __show_error(tizen_error_code); + } + get_user_choice(); +} + +void fido_attestation_type_cb_list(fido_auth_attestation_type_e att_type, void *user_data) +{ + char *str = (char *) user_data; + + char tmp[1024] = {0,}; + if(att_type != -1) { + sprintf(tmp, " | Attestation Type = [%d]", att_type); + strcat(str, tmp); + } +} + +static char * +__get_authinfo_string(const fido_authenticator_h auth) +{ + char str[5000] = {0,}; + str[0] = '\0'; + strcpy(str, "DISCOVER RESPONSE"); + char tmp[1024] = {0,}; + + char *title = NULL; + fido_authenticator_get_title(auth, &title); + if(title) { + sprintf(tmp, " | Title = [%s]", title); + strcat(str, tmp); + } + free(title); + + char *aaid = NULL; + fido_authenticator_get_aaid(auth, &aaid); + if(aaid) { + sprintf(tmp, " | AAID = [%s]", aaid); + strcat(str, tmp); + } + free(aaid); + + char *description = NULL; + fido_authenticator_get_description(auth, &description); + if(description) { + sprintf(tmp, " | Description = [%s]", description); + strcat(str, tmp); + } + free(description); + + char *scheme = NULL; + fido_authenticator_get_assertion_scheme(auth, &scheme); + if(scheme) { + sprintf(tmp, " | Scheme = [%s]", scheme); + strcat(str, tmp); + } + free(scheme); + + fido_authenticator_foreach_attestation_type(auth, fido_attestation_type_cb_list, str); + + fido_auth_algo_e get_algo = -1; + fido_authenticator_get_algorithm(auth, &get_algo); + if(get_algo != -1) { + sprintf(tmp, " | Algo = [%d]", get_algo); + strcat(str, tmp); + } + + fido_auth_user_verify_type_e user_ver = -1; + fido_authenticator_get_verification_method(auth, &user_ver); + if(user_ver != -1) { + sprintf(tmp, " | Verification = [%d]", user_ver); + strcat(str, tmp); + } + + fido_auth_key_protection_type_e key_protection = -1; + fido_authenticator_get_key_protection_method(auth, &key_protection); + if(key_protection != -1) { + sprintf(tmp, " | Key Protection = [%d]", key_protection); + strcat(str, tmp); + } + + fido_auth_matcher_protection_type_e matcher_protection = -1; + fido_authenticator_get_matcher_protection_method(auth, &matcher_protection); + if(matcher_protection != -1) { + sprintf(tmp, " | Matcher Protection = [%d]", matcher_protection); + strcat(str, tmp); + } + + fido_auth_attachment_hint_e attachment_hint = -1; + fido_authenticator_get_attachment_hint(auth, &attachment_hint); + if(attachment_hint != -1) { + sprintf(tmp, " | Attachment Hint = [%d]", attachment_hint); + strcat(str, tmp); + } + + fido_auth_tc_display_type_e tc_discplay = -1; + fido_authenticator_get_tc_discplay(auth, &tc_discplay); + if(tc_discplay != -1) { + sprintf(tmp, " | Tc Display = [%d]", tc_discplay); + strcat(str, tmp); + } + + char *tc_display_type = NULL; + fido_authenticator_get_tc_display_type(auth, &tc_display_type); + if(tc_display_type) { + sprintf(tmp, " | Tc Display Type = [%s]", tc_display_type); + strcat(str, tmp); + } + free(tc_display_type); + + char *icon = NULL; + fido_authenticator_get_icon(auth, &icon); + if(icon) { + sprintf(tmp, " | Icon = [%s]", icon); + strcat(str, tmp); + } + free(icon); + + return strdup(str); +} + +static void +auth_list_cb(const fido_authenticator_h auth, void *user_data) +{ + char *auth_info_str = __get_authinfo_string(auth); + if (auth_info_str != NULL) + printf("%s", auth_info_str); + +} + +void +find_auth(void) +{ + int ret = fido_foreach_authenticator(auth_list_cb, NULL); + + if (ret != FIDO_ERROR_NONE) { + __show_error(ret); + } + get_user_choice(); +} + +void +check_supported(void) +{ + bool is_supported = false; + int ret = fido_uaf_is_supported(json_reg, &is_supported); + + if (ret != FIDO_ERROR_NONE) { + char *error_string = __get_error_code(ret); + + printf("Check policy resonse: %s\n", error_string); + fflush(stdout); + free(error_string); + } + else { + if (is_supported == true) { + printf("Check policy resonse: TRUE\n"); + fflush(stdout); + } + else { + printf("Check policy resonse: FALSE\n"); + fflush(stdout); + } + } + get_user_choice(); +} + +void +registration(void) +{ + int ret = fido_uaf_get_response_message(json_reg, NULL, __process_cb, NULL); + if (ret != FIDO_ERROR_NONE) { + __show_error(ret); + get_user_choice(); + } +} + +static void +_process_cb(fido_error_e tizen_error_code, const char *uaf_response, void *user_data) +{ + if (tizen_error_code == 0 && uaf_response != NULL) { + fflush(stdout); + printf("UAF Response =%s\n", uaf_response); + fflush(stdout); + } + else { + __show_error(tizen_error_code); + } + get_user_choice(); +} + +void +authentication(void) +{ + if (json_auth != NULL) { + int ret = fido_uaf_get_response_message(json_auth, NULL, _process_cb, NULL); + + if (ret != FIDO_ERROR_NONE) { + __show_error(ret); + get_user_choice(); + } + } +} + +static void +_process_dereg_cb(fido_error_e tizen_error_code, const char *uaf_response, void *user_data) +{ + char *str = __get_error_code(tizen_error_code); + printf("%s\n", str); + fflush(stdout); + free(str); + get_user_choice(); +} + +void +dereg(void) +{ + if (json_reg != NULL) { + int ret = fido_uaf_get_response_message(json_dereg, NULL, _process_dereg_cb, NULL); + + if (ret != FIDO_ERROR_NONE) { + __show_error(ret); + get_user_choice(); + } + } +} + +static void +_process_cb_for_notify_pos(fido_error_e tizen_error_code, const char *uaf_response, void *user_data) +{ + if (tizen_error_code == 0) { + + int ret = fido_uaf_set_server_result(FIDO_SERVER_STATUS_CODE_OK, uaf_response); + + char *str = __get_error_code(ret); + printf("%s\n", str); + fflush(stdout); + free(str); + } + else { + __show_error(tizen_error_code); + } + get_user_choice(); +} + +void +set_result_success(void) +{ + if (json_reg != NULL) { + int ret = fido_uaf_get_response_message(json_reg, NULL, _process_cb_for_notify_pos, NULL); + + if (ret != FIDO_ERROR_NONE) { + __show_error(ret); + get_user_choice(); + } + } +} + +static void +_process_cb_for_notify_neg(fido_error_e tizen_error_code, const char *uaf_response, void *user_data) +{ + if (tizen_error_code == 0) { + + int ret = fido_uaf_set_server_result(0, uaf_response); + + char *str = __get_error_code(ret); + printf("%s\n", str); + fflush(stdout); + free(str); + } + else { + __show_error(tizen_error_code); + } + get_user_choice(); +} + +void +set_result_failure(void) +{ + if (json_reg != NULL) { + int ret = fido_uaf_get_response_message(json_reg, NULL, _process_cb_for_notify_neg, NULL); + + if (ret != FIDO_ERROR_NONE) { + __show_error(ret); + get_user_choice(); + } + } +} + +void +get_user_choice(void) +{ + int sel_opt = 0; + const int options[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + const char *names[8] = { "Find Authenticator", + "Check UAF Message Supported", + "Registration", + "Authentication", + "De-Registration", + "Set Server Result with Success", + "Set Server Result with Failure", + "Exit"}; + + sel_opt = show_menu("Select action:", options, names, 8); + switch (sel_opt) { + case 1: + find_auth(); + break; + + case 2: + check_supported(); + break; + + case 3: + registration(); + break; + + case 4: + authentication(); + break; + + case 5: + dereg(); + break; + + case 6: + set_result_success(); + break; + + case 7: + set_result_failure(); + break; + + default: + exit(1); + } +} + +int +main(void) +{ + GMainLoop *mainloop = NULL; + + mainloop = g_main_loop_new(NULL, FALSE); + + get_user_choice(); + + g_main_loop_run(mainloop); + + return 0; +} diff --git a/test/shell_tc/fido_shell_tc_util.c b/test/shell_tc/fido_shell_tc_util.c new file mode 100644 index 0000000..c76ecf0 --- /dev/null +++ b/test/shell_tc/fido_shell_tc_util.c @@ -0,0 +1,256 @@ +/** + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fido_shell_tc_util.h" +#include "fido.h" + +#include +#include +#include + +void + print_fail_result( + const char *action_name, + int action_return_value) +{ + printf(TEXT_RED + "Error with code %i was occurred during action '%s'" + TEXT_RESET "\n", + action_return_value, + action_name); +} + +void +print_done_result(const char *action_name) +{ + printf(TEXT_YELLOW + "Action '%s' was finished" + TEXT_RESET "\n", + action_name); +} + +void +print_success_result(const char *action_name) +{ + printf(TEXT_GREEN + "Action '%s' was finished successfully" + TEXT_RESET + "\n", action_name); +} + +void +print_action_result( + const char *action_name, + int action_return_value, + notification_type_e notification_type_e) +{ + switch (notification_type_e) { + case FAIL_OR_SUCCESSS: + if (FIDO_ERROR_NONE != action_return_value) + print_fail_result(action_name, action_return_value); + else + print_success_result(action_name); + + break; + case FAIL_OR_DONE: + if (FIDO_ERROR_NONE != action_return_value) + print_fail_result(action_name, action_return_value); + else + print_done_result(action_name); + + break; + default: + print_done_result(action_name); + } +} + +int +input_string(const char *prompt, size_t max_len, char **string) +{ + printf("\n"); + printf("%s ", prompt); + + if (scanf("\n") != 0) + return -1; + + char buffer[max_len]; + int last_char = 0; + buffer[last_char] = '\0'; + buffer[sizeof(buffer) - 1] = ~'\0'; + if (NULL == fgets(buffer, sizeof(buffer), stdin)) + return -1; + + size_t real_string_len = strlen(buffer); + buffer[real_string_len - 1] = '\0'; + *string = (char*)malloc(real_string_len * sizeof(char)); + if (*string == NULL) + return -1; + + strncpy(*string, buffer, real_string_len); + + return strlen(*string); +} + +int +input_size(const char *prompt, size_t max_size, size_t *size) +{ + printf("\n"); + printf("%s ", prompt); + + if (scanf("%20zu", size) == 0) { + if (scanf("%*[^\n]%*c") != 0) { + printf("ERROR: Reading the input line error.\n"); + return -1; + } + printf("ERROR: Incorrect input.\n"); + return -1; + } + scanf("%*[^\n]%*c"); + + return (*size > max_size ? -1 : 0); +} + +int +input_int(const char *prompt, int min_value, int max_value, int *value) +{ + printf("\n"); + printf("%s ", prompt); + + if (scanf("%20i", value) == 0) { + if (scanf("%*[^\n]%*c") != 0) { + printf("ERROR: Reading the input line error.\n"); + return -1; + } + printf("ERROR: Incorrect input.\n"); + return -1; + } + scanf("%*[^\n]%*c"); + + return (*value < min_value || *value > max_value ? -1 : 0); +} + +int +input_double( + const char *prompt, + double min_value, + double max_value, + double *value) +{ + printf("\n"); + printf("%s ", prompt); + + if (scanf("%20lf", value) == 0) { + if (scanf("%*[^\n]%*c") != 0) { + printf("ERROR: Reading the input line error.\n"); + return -1; + } + printf("ERROR: Incorrect input.\n"); + return -1; + } + scanf("%*[^\n]%*c"); + + return (*value < min_value || *value > max_value ? -1 : 0); +} + +bool +show_confirm_dialog(const char *title) +{ + const int options[2] = {1, 2}; + const char *names[2] = { "No", "Yes" }; + + bool answer = false; + + int sel = -1; + while (sel == -1) { + sel = show_menu(title, options, names, 2); + switch (sel) { + case 1: + answer = false; + break; + case 2: + answer = true; + break; + default: + sel = -1; + printf("ERROR: Incorrect input.\n"); + continue; + } + } + + return answer; +} + +int +show_menu( + const char *title, + const int *options, + const char **names, + int number_of_option) +{ + if (NULL == title || NULL == options || NULL == names || 0 >= number_of_option) + return -1; + + int number_size = 1; + + int tn_counter = number_of_option; + while (tn_counter /= 10) + ++number_size; + + int max_len = strlen(title) - number_size - 2; + + int i = 0; + for (i = 0; i < number_of_option; ++i) { + const int temp_len = strlen(names[i]); + if (max_len < temp_len) + max_len = temp_len; + } + + const int full_size = number_size + 2 + max_len; + + printf("\n**"); + for (i = 0; i < full_size; ++i) + printf("*"); + printf("**\n"); + + printf("* %-*s *\n", full_size, title); + + printf("*-"); + for (i = 0; i < full_size; ++i) + printf("-"); + printf("-*\n"); + + for (i = 0; i < number_of_option; ++i) + printf("* %0*i. %-*s *\n", number_size, options[i], max_len, names[i]); + + printf("**"); + for (i = 0; i < full_size; ++i) + printf("*"); + printf("**\n\n"); + + int selection = 0; + printf("Your choice: "); + if (scanf("%25i", &selection) == 0) { + if (scanf("%*[^\n]%*c") != 0) + printf("ERROR: Reading the input line error.\n"); + + printf("ERROR: Incorrect input.\n"); + return -1; + } + scanf("%*[^\n]%*c"); + + return selection; +} + diff --git a/test/shell_tc/fido_shell_tc_util.h b/test/shell_tc/fido_shell_tc_util.h new file mode 100644 index 0000000..add632c --- /dev/null +++ b/test/shell_tc/fido_shell_tc_util.h @@ -0,0 +1,180 @@ + +#ifndef __FIDO_SHELL_TC_UTIL_H_ +#define __FIDO_SHELL_TC_UTIL_H_ + +#include +#include +#include + +#define TEXT_RED "\x1b[31m" +#define TEXT_GREEN "\x1b[32m" +#define TEXT_YELLOW "\x1b[33m" +#define TEXT_BLUE "\x1b[34m" +#define TEXT_MAGENTA "\x1b[35m" +#define TEXT_CYAN "\x1b[36m" +#define TEXT_RESET "\x1b[0m" + +#ifdef ROOTSTRAP_OUT + +#define LOGD(...) \ +do \ +{ \ + printf("<%s:%d>", __FUNCTION__, __LINE__); \ + printf(TEXT_CYAN); \ + printf(__VA_ARGS__); \ + printf(TEXT_RESET "\n"); \ +} while(0) + +#define LOGI(...) \ +do \ +{ \ + printf("<%s:%d>", __FUNCTION__, __LINE__); \ + printf(TEXT_GREEN); \ + printf(__VA_ARGS__); \ + printf(TEXT_RESET "\n"); \ +} while(0) + +#define LOGW(...) \ +do \ +{ \ + printf("<%s:%d>", __FUNCTION__, __LINE__); \ + printf(TEXT_YELLOW); \ + printf(__VA_ARGS__); \ + printf(TEXT_RESET "\n"); \ +} while(0) + +#define LOGE(...) \ +do \ +{ \ + printf("<%s:%d>", __FUNCTION__, __LINE__); \ + printf(TEXT_RED); \ + printf(__VA_ARGS__); \ + printf(TEXT_RESET "\n"); \ +} while(0) + +#endif + + +typedef enum +{ + FAIL_OR_SUCCESSS, + FAIL_OR_DONE +} notification_type_e; + +/** + * @brief Prints success result of action. + * + * @since_tizen 3.0 + * @param [in] action_name Name of action which result will be printed + * @param [in] action_return_value Return value of action + */ +void print_fail_result( + const char *action_name, + int action_return_value); + +/** + * @brief Prints success result of action. + * + * @since_tizen 3.0 + * @param [in] action_name Name of action which result will be printed + */ +void print_done_result(const char *action_name); + +/** + * @brief Prints success result of action. + * + * @since_tizen 3.0 + * @param [in] action_name Name of action which result will be printed + */ +void print_success_result(const char *action_name); + +/** + * @brief Prints action result. + * + * @since_tizen 3.0 + * @param [in] action_name Name of action which result will be printed + * @param [in] action_return_value Return value of action + * @param [in] notification_type_e Type of notification + */ +void print_action_result( + const char *action_name, + int action_return_value, + notification_type_e notification_type_e); + +/** + * @brief Gets srting from console. + * + * @since_tizen 3.0 + * @param [in] prompt The prompt before getting string value + * @param [in] max_len Maximum length of the string which will be got + * @param [out] string Output string which was got from console + * @return Length of the output string on success, otherwise a negative error value + */ +int input_string(const char *prompt, size_t max_len, char **string); + +/** + * @brief Gets unsigned integer from console. + * + * @since_tizen 3.0 + * @param [in] prompt The prompt before getting unsigned integer value + * @param [in] max_size The thresold for maximum possible value + * @param [out] size The output unsigned integer which was got from console + * @return @c 0 on success, otherwise a negative error value + */ +int input_size(const char *prompt, size_t max_size, size_t *size); + +/** + * @brief Gets integer from console. + * + * @since_tizen 3.0 + * @param [in] prompt The prompt before getting integer value + * @param [in] min_value The thresold for minimum possible value + * @param [in] max_value The thresold for maximum possible value + * @param [out] value The output integer which was got from console + * @return @c 0 on success, otherwise a negative error value + */ +int input_int(const char *prompt, int min_value, int max_value, int *value); + +/** + * @brief Gets double from console. + * + * @since_tizen 3.0 + * @param [in] prompt The prompt before getting double value + * @param [in] min_value The thresold for minimum possible value + * @param [in] max_value The thresold for maximum possible value + * @param [out] value The output double which was got from console + * @return @c 0 on success, otherwise a negative error value + */ +int input_double(const char *prompt, double min_value, double max_value, double *value); + +/** + * @brief Shows confirm dialog in console and gets answer (Yes/No). + * + * @since_tizen 3.0 + * @param [in] title The title for confirm dialog which will be printed + * before input of the answer + * @return false if answer is "No" and true if answer is "Yes" + */ +bool show_confirm_dialog(const char *title); + +/** + * @brief Shows menu in console and allows to get item from the array of options. + * + * @since_tizen 3.0 + * @param [in] title The title for show menu which will be printed + * before options + * @param [in] options The array with integer numbers of options + * which will be shown + * @param [in] names The array with names of options which will + * be shown + * @param [in] number_of_option The number of options which will be shown + * @return The selected item positive number from options array on success, + * otherwise a negative error value + */ +int show_menu( + const char *title, + const int *options, + const char **names, + int number_of_option); + +#endif /* __FIDO_SHELL_TC_UTIL_H_ */