summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndriy Byzhynar <AByzhynar@luxoft.com>2018-02-23 17:54:43 +0200
committerAKalinich-Luxoft <AKalinich@luxoft.com>2018-06-15 17:09:13 +0300
commit2e96298b93b66ec9b9b15663d17dc62df3ab77c4 (patch)
tree9532a59c82176b115b7c7bd1c0cc4d73d0f78879
parent90ee6ad4af35d9fdbc00df6c72a8fb8805f3c5da (diff)
downloadsdl_core-2e96298b93b66ec9b9b15663d17dc62df3ab77c4.tar.gz
Implement fully functional GetSystemTime feature
Implemented fully working GetSystemTime feature Fixed UT in the security manager due to code changes Disable randomly failed test
-rw-r--r--src/appMain/CMakeLists.txt2
-rw-r--r--src/appMain/life_cycle.cc9
-rw-r--r--src/appMain/life_cycle.h7
-rw-r--r--src/components/application_manager/CMakeLists.txt11
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h7
-rw-r--r--src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h69
-rw-r--r--src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h72
-rw-r--r--src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h75
-rw-r--r--src/components/application_manager/include/application_manager/message_helper.h9
-rw-r--r--src/components/application_manager/include/application_manager/smart_object_keys.h16
-rw-r--r--src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h157
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc4
-rw-r--r--src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_request.cc49
-rw-r--r--src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_response.cc57
-rw-r--r--src/components/application_manager/src/commands/hmi/on_system_time_ready_notification.cc56
-rw-r--r--src/components/application_manager/src/commands/hmi/request_to_hmi.cc4
-rw-r--r--src/components/application_manager/src/hmi_command_factory.cc18
-rw-r--r--src/components/application_manager/src/message_helper/message_helper.cc14
-rw-r--r--src/components/application_manager/src/policies/policy_handler.cc10
-rw-r--r--src/components/application_manager/src/smart_object_keys.cc17
-rw-r--r--src/components/application_manager/src/system_time/system_time_handler_impl.cc169
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc1
-rw-r--r--src/components/include/policy/policy_regular/policy/policy_manager.h6
-rw-r--r--src/components/include/protocol_handler/protocol_handler.h6
-rw-r--r--src/components/include/security_manager/crypto_manager.h13
-rw-r--r--src/components/include/security_manager/security_manager.h46
-rw-r--r--src/components/include/security_manager/security_manager_listener.h6
-rw-r--r--src/components/include/security_manager/ssl_context.h11
-rw-r--r--src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h2
-rw-r--r--src/components/include/test/protocol_handler/mock_protocol_handler.h1
-rw-r--r--src/components/include/test/security_manager/mock_crypto_manager.h4
-rw-r--r--src/components/include/test/security_manager/mock_security_manager.h10
-rw-r--r--src/components/include/test/security_manager/mock_security_manager_listener.h1
-rw-r--r--src/components/include/test/security_manager/mock_ssl_context.h2
-rw-r--r--src/components/include/test/utils/mock_system_time_handler.h69
-rw-r--r--src/components/interfaces/HMI_API.xml10
-rw-r--r--src/components/policy/policy_regular/include/policy/cache_manager.h6
-rw-r--r--src/components/policy/policy_regular/include/policy/cache_manager_interface.h7
-rw-r--r--src/components/policy/policy_regular/include/policy/policy_manager_impl.h2
-rw-r--r--src/components/policy/policy_regular/src/cache_manager.cc7
-rw-r--r--src/components/policy/policy_regular/src/policy_manager_impl.cc7
-rw-r--r--src/components/protocol_handler/include/protocol_handler/handshake_handler.h7
-rw-r--r--src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h4
-rw-r--r--src/components/protocol_handler/src/handshake_handler.cc11
-rw-r--r--src/components/protocol_handler/src/protocol_handler_impl.cc46
-rw-r--r--src/components/protocol_handler/test/protocol_handler_tm_test.cc49
-rw-r--r--src/components/security_manager/include/security_manager/crypto_manager_impl.h24
-rw-r--r--src/components/security_manager/include/security_manager/security_manager_impl.h80
-rw-r--r--src/components/security_manager/src/crypto_manager_impl.cc67
-rw-r--r--src/components/security_manager/src/security_manager_impl.cc175
-rw-r--r--src/components/security_manager/src/ssl_context_impl.cc96
-rw-r--r--src/components/security_manager/test/crypto_manager_impl_test.cc9
-rw-r--r--src/components/security_manager/test/security_manager_test.cc129
-rw-r--r--src/components/security_manager/test/ssl_certificate_handshake_test.cc3
-rw-r--r--src/components/utils/CMakeLists.txt1
-rw-r--r--src/components/utils/include/utils/system_time_handler.h151
-rw-r--r--src/components/utils/src/system_time_handler.cc63
57 files changed, 1737 insertions, 227 deletions
diff --git a/src/appMain/CMakeLists.txt b/src/appMain/CMakeLists.txt
index 2acc0bf3ae..06738713bd 100644
--- a/src/appMain/CMakeLists.txt
+++ b/src/appMain/CMakeLists.txt
@@ -109,7 +109,9 @@ set(LIBRARIES
jsoncpp
ConfigProfile
Resumption
+ SystemTimeLibrary
)
+
if(REMOTE_CONTROL)
SET (LIBRARIES
${LIBRARIES}
diff --git a/src/appMain/life_cycle.cc b/src/appMain/life_cycle.cc
index fc8441f28c..90a23465be 100644
--- a/src/appMain/life_cycle.cc
+++ b/src/appMain/life_cycle.cc
@@ -34,6 +34,7 @@
#include "utils/signals.h"
#include "utils/make_shared.h"
#include "config_profile/profile.h"
+#include "application_manager/system_time/system_time_handler_impl.h"
#include "resumption/last_state_impl.h"
#ifdef ENABLE_SECURITY
@@ -119,7 +120,11 @@ bool LifeCycle::StartComponents() {
}
#ifdef ENABLE_SECURITY
- security_manager_ = new security_manager::SecurityManagerImpl();
+ auto system_time_handler =
+ std::unique_ptr<application_manager::SystemTimeHandlerImpl>(
+ new application_manager::SystemTimeHandlerImpl(*app_manager_));
+ security_manager_ =
+ new security_manager::SecurityManagerImpl(std::move(system_time_handler));
crypto_manager_ = new security_manager::CryptoManagerImpl(
utils::MakeShared<security_manager::CryptoManagerSettingsImpl>(
profile_, app_manager_->GetPolicyHandler().RetrieveCertificate()));
@@ -131,7 +136,7 @@ bool LifeCycle::StartComponents() {
security_manager_->set_crypto_manager(crypto_manager_);
security_manager_->AddListener(app_manager_);
- app_manager_->AddPolicyObserver(crypto_manager_);
+ app_manager_->AddPolicyObserver(security_manager_);
app_manager_->AddPolicyObserver(protocol_handler_);
if (!crypto_manager_->Init()) {
LOG4CXX_ERROR(logger_, "CryptoManager initialization fail.");
diff --git a/src/appMain/life_cycle.h b/src/appMain/life_cycle.h
index db18892cd3..e37da3fa1d 100644
--- a/src/appMain/life_cycle.h
+++ b/src/appMain/life_cycle.h
@@ -33,8 +33,9 @@
#ifndef SRC_APPMAIN_LIFE_CYCLE_H_
#define SRC_APPMAIN_LIFE_CYCLE_H_
#include <thread>
+#include <unistd.h>
#include "utils/macro.h"
-#include "unistd.h"
+#include "utils/shared_ptr.h"
#include "config_profile/profile.h"
#include "hmi_message_handler/hmi_message_handler_impl.h"
@@ -65,6 +66,10 @@ class SecurityManagerImpl;
} // namespace security_manager
#endif // ENABLE_SECURITY
+namespace utils {
+class SystemTimeHandler;
+} // namespace utils
+
namespace main_namespace {
class LifeCycle {
public:
diff --git a/src/components/application_manager/CMakeLists.txt b/src/components/application_manager/CMakeLists.txt
index e9f2f8ec7b..966dbee353 100644
--- a/src/components/application_manager/CMakeLists.txt
+++ b/src/components/application_manager/CMakeLists.txt
@@ -52,6 +52,7 @@ include_directories (
${COMPONENTS_DIR}/config_profile/include
${COMPONENTS_DIR}/request_watchdog/include
${COMPONENTS_DIR}/resumption/include
+ ${COMPONENTS_DIR}/system_time/
${COMPONENTS_DIR}/rpc_base/include
${COMPONENTS_DIR}/interfaces
${POLICY_PATH}/include/
@@ -85,6 +86,9 @@ set (MESSAGE_HELPER_PATHS
)
collect_sources(MESSAGE_HELPER_SOURCES "${MESSAGE_HELPER_PATHS}")
+set (SYSTEM_TIME_SOURCES
+ ${AM_SOURCE_DIR}/src/system_time/system_time_handler_impl.cc
+)
set (POLICIES_SOURCE_DIR
${AM_SOURCE_DIR}/src/policies
@@ -146,6 +150,9 @@ set (HMI_COMMANDS_SOURCES
${COMMANDS_SOURCE_DIR}/hmi/activate_app_response.cc
${COMMANDS_SOURCE_DIR}/hmi/get_system_info_request.cc
${COMMANDS_SOURCE_DIR}/hmi/get_system_info_response.cc
+ ${COMMANDS_SOURCE_DIR}/hmi/basic_communication_get_system_time_request.cc
+ ${COMMANDS_SOURCE_DIR}/hmi/basic_communication_get_system_time_response.cc
+ ${COMMANDS_SOURCE_DIR}/hmi/on_system_time_ready_notification.cc
${COMMANDS_SOURCE_DIR}/hmi/sdl_get_list_of_permissions_request.cc
${COMMANDS_SOURCE_DIR}/hmi/sdl_get_list_of_permissions_response.cc
${COMMANDS_SOURCE_DIR}/hmi/sdl_get_user_friendly_message_request.cc
@@ -447,6 +454,10 @@ target_link_libraries("AMHMICommandsLibrary" ${LIBRARIES} AMEventEngine)
add_library("MessageHelper" ${MESSAGE_HELPER_SOURCES})
target_link_libraries("MessageHelper" ${LIBRARIES})
+add_library("SystemTimeLibrary" ${SYSTEM_TIME_SOURCES})
+target_link_libraries("SystemTimeLibrary" ${LIBRARIES} AMEventEngine)
+add_dependencies("MessageHelper" HMI_API MOBILE_API)
+
add_library("AMMobileCommandsLibrary" ${MOBILE_COMMANDS_SOURCES} )
target_link_libraries("AMMobileCommandsLibrary" ${LIBRARIES} AMEventEngine)
diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h
index 30816e0ffa..905e3cf057 100644
--- a/src/components/application_manager/include/application_manager/application_manager_impl.h
+++ b/src/components/application_manager/include/application_manager/application_manager_impl.h
@@ -815,6 +815,13 @@ class ApplicationManagerImpl
security_manager::SSLContext::HandshakeResult result) OVERRIDE;
/**
+ * @brief OnHandshakeFailed currently does nothing.
+ * This method is declared as pure virtual in common base class
+ * therefore it has to be present and should be implemented
+ * to allow creation of current class instances
+ */
+ void OnHandshakeFailed() OVERRIDE;
+ /**
* @brief Notification that certificate update is required.
*/
void OnCertificateUpdateRequired() OVERRIDE;
diff --git a/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h
new file mode 100644
index 0000000000..1638b2f51b
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_request.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_REQUEST_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_REQUEST_H_
+
+#include "application_manager/commands/hmi/request_to_hmi.h"
+#include "utils/macro.h"
+
+namespace application_manager {
+namespace commands {
+
+/**
+ * @brief The BasicCommunicationGetSystemTimeRequest class sends the request
+ * to the HMI in order to receive current system time.
+ */
+class BasicCommunicationGetSystemTimeRequest : public RequestToHMI {
+ public:
+ /**
+ * @brief BasicCommunicationGetSystemTimeRequest does nothing except of
+ * initializing base class with the passed parameters.
+ * @param message the message to send to HMI
+ * @param application_manager application manager. Location service which
+ * is provides neccessary api to send the request.
+ */
+ BasicCommunicationGetSystemTimeRequest(
+ const MessageSharedPtr& message, ApplicationManager& application_manager);
+
+ private:
+ /**
+ * @brief onTimeOut allows to handle case when
+ * system does not respond for certain request in
+ * appropriate time window.
+ */
+ void onTimeOut() FINAL;
+};
+
+} // namespace commands
+} // namespace application_manager
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_REQUEST_H_
diff --git a/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h
new file mode 100644
index 0000000000..1bf7447c7d
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/commands/hmi/basic_communication_get_system_time_response.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_RESPONSE_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_RESPONSE_H_
+
+#include "application_manager/commands/hmi/response_from_hmi.h"
+
+#include "utils/macro.h"
+#include "application_manager/application_manager_impl.h"
+
+namespace application_manager {
+
+namespace commands {
+
+/**
+ * @brief The BasicCommunicationGetSystemTimeResponse class represents the
+ * HMI response which is contains data obtained from HMI.
+ */
+class BasicCommunicationGetSystemTimeResponse : public ResponseFromHMI {
+ public:
+ /**
+ * @brief BasicCommunicationGetSystemTimeResponse does nothing except of
+ * initializing base class with the passed parameters.
+ * @param message the message to send to HMI
+ * @param application_manager Location service which which is provides
+ * neccessary api to send the request.
+ */
+ BasicCommunicationGetSystemTimeResponse(
+ const MessageSharedPtr& message, ApplicationManager& application_manager);
+
+ private:
+ /**
+ * @brief Run takes the message obtained from the HMI and
+ * sends this data to the subscribed on certain event class
+ */
+ void Run() FINAL;
+};
+
+} // namespace commands
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_BASIC_COMMUNICATION_GET_SYSTEM_TIME_RESPONSE_H_
diff --git a/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h b/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h
new file mode 100644
index 0000000000..9b8763da42
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/commands/hmi/on_system_time_ready_notification.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_ON_SYSTEM_TIME_READY_NOTIFICATION_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_ON_SYSTEM_TIME_READY_NOTIFICATION_H_
+
+#include "application_manager/commands/hmi/notification_from_hmi.h"
+#include "application_manager/application_manager_impl.h"
+
+namespace application_manager {
+
+namespace commands {
+
+/**
+ * @brief OnSystemTimeReadyNotification command class.
+ * Notifies SDL whenever system time module is ready.
+ * It could be GPS or any other module which is allows
+ * to obtain system time. Once SDL receive this notification
+ * it is allowed to use GetSystemTimeRequest to rerieve system time.
+ */
+class OnSystemTimeReadyNotification : public NotificationFromHMI {
+ public:
+ /**
+ * @brief OnSystemTimeReadyNotification create the command.
+ * @param message content of the command. Passed directy to base class.
+ */
+ OnSystemTimeReadyNotification(const MessageSharedPtr& message,
+ ApplicationManager& application_manager);
+
+ /**
+ * @brief ~OnSystemTimeReadyNotification destroys the command object.
+ */
+ ~OnSystemTimeReadyNotification();
+
+ private:
+ /**
+ * @brief Run creates SystemTimeReady event
+ * and notifies all the subscribers.
+ */
+ void Run() FINAL;
+};
+
+} // namespace commands
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMANDS_HMI_ON_SYSTEM_TIME_READY_NOTIFICATION_H_
diff --git a/src/components/application_manager/include/application_manager/message_helper.h b/src/components/application_manager/include/application_manager/message_helper.h
index 57a2f847bf..4cd18b3c36 100644
--- a/src/components/application_manager/include/application_manager/message_helper.h
+++ b/src/components/application_manager/include/application_manager/message_helper.h
@@ -107,6 +107,15 @@ class MessageHelper {
static void SendDecryptCertificateToHMI(const std::string& file_name,
ApplicationManager& app_mngr);
+ /**
+ * @brief SendGetSystemTimeRequest sends mentioned request to HMI.
+ * @param correlation_id the message correlation id, required for proper
+ * response processing.
+ * @param app_mngr
+ */
+ static void SendGetSystemTimeRequest(const uint32_t correlation_id,
+ ApplicationManager& app_mngr);
+
/*
* @brief Retrieve vehicle data map for param name in mobile request
* to VehicleDataType
diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h
index ce5b68ee3c..50d70591c9 100644
--- a/src/components/application_manager/include/application_manager/smart_object_keys.h
+++ b/src/components/application_manager/include/application_manager/smart_object_keys.h
@@ -422,7 +422,19 @@ extern const char* kFull;
extern const char* kLimited;
extern const char* kBackground;
extern const char* kNone;
-}
+} // namespace hmi_levels
+
+namespace time_keys {
+extern const char* millisecond;
+extern const char* second;
+extern const char* minute;
+extern const char* hour;
+extern const char* day;
+extern const char* month;
+extern const char* year;
+extern const char* tz_hour;
+extern const char* tz_minute;
+} // namespace time_keys
namespace hmi_request {
extern const char* parent_id;
@@ -495,7 +507,7 @@ extern const char* num_custom_presets_available;
extern const char* urls;
extern const char* policy_app_id;
extern const char* enabled;
-
+extern const char* system_time;
} // namespace hmi_response
namespace hmi_notification {
diff --git a/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h b/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h
new file mode 100644
index 0000000000..28ba629e19
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/system_time/system_time_handler_impl.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_SYSTEM_TIME_SYSTEM_TIME_HANDLER_IMPL_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_SYSTEM_TIME_SYSTEM_TIME_HANDLER_IMPL_H_
+
+#include <time.h>
+#include <vector>
+
+#include "utils/lock.h"
+#include "utils/macro.h"
+#include "utils/system_time_handler.h"
+#include "application_manager/application_manager_impl.h"
+#include "application_manager/event_engine/event_observer.h"
+
+namespace application_manager {
+
+/**
+ * @brief The SystemTimeHandlerImpl class.
+ * Responsible for the system time notification. It keeps the list
+ * of system time listeners, sends appropriate request to the system
+ * and notifies the listeners with new time right after response has appeared.
+ */
+class SystemTimeHandlerImpl : public utils::SystemTimeHandler,
+ public event_engine::EventObserver {
+ public:
+ /**
+ * @brief SystemTimeHandlerImpl creates the instance of the class.
+ */
+ explicit SystemTimeHandlerImpl(ApplicationManager& application_manager);
+
+ /**
+ * @brief ~SystemTimeHandlerImpl
+ */
+ ~SystemTimeHandlerImpl();
+
+ private:
+ /**
+ * @brief on_event allows to process certain events from the system.
+ * Event which are handles within this methods are: OnSystemTimeReady
+ * in order to send system time query and GetSystemTimeResponse in order
+ * to retrieve utc time and notify all the listeners with new time value.
+ */
+ void on_event(const application_manager::event_engine::Event& event) FINAL;
+
+ /**
+ * @brief DoSystemTimeQuery sends the appropriate request to the system
+ * and subscribes the class to the response. This is asynchronous request
+ * thus it won't block until the system respond and returns immediately.
+ */
+ void DoSystemTimeQuery() FINAL;
+
+ /**
+ * @brief DoSubscribe allows to subscribe certain listener for
+ * SystemTime. This certain implementation does not maintain
+ * listeners collection instead it save the pointer to listener.
+ * @note the class is not reponsible for the pointer's lifecycle.
+ * So consider to explicitly unsibsscribe from event when listener
+ * is going to be destroyed.
+ * @param listener the listener which will be notified
+ * in case of SystemTime appeared.
+ */
+ void DoSubscribe(utils::SystemTimeListener* listener) FINAL;
+
+ /**
+ * @brief DoUnsubscribe assigns the pointer to listener to NULL.
+ * This certain implementation ignores passed parameter.
+ * @param listener pointer to the object which should be
+ * unsubscribed from events.
+ */
+ void DoUnsubscribe(utils::SystemTimeListener* listener) FINAL;
+
+ /**
+ * @brief FetchSystemTime this method allows to obtain
+ * recently received utc time.
+ * @note it is up to user to check whether the returned
+ * argument is valid
+ * @return the time value returned by system.
+ */
+ time_t FetchSystemTime() FINAL;
+
+ /**
+ * @brief SendTimeRequest sends the request to the system
+ * and subscribes for response.
+ */
+ void SendTimeRequest();
+
+ /**
+ * @brief ProcessSystemTimeResponse allows to process GetSystemTimeResponse
+ * @param event contains response parameters aka "systemTime".
+ */
+ void ProcessSystemTimeResponse(
+ const application_manager::event_engine::Event& event);
+
+ /**
+ * @brief ProcessSystemTimeReadyNotification allows to process
+ * OnSystemTimeready notification
+ * from HMI. It unsubscribes from the mentioned notification and sends
+ * GetSystemTimeRequest to HMI in order to obtain system time
+ */
+ void ProcessSystemTimeReadyNotification();
+
+ /**
+ * @brief Checks if UTC time is ready to provided by HMI
+ * and can be requested by GetSystemTime request
+ * @return True if HMI is ready to provide UTC time
+ * otherwise False
+ */
+ bool utc_time_can_be_received() const FINAL;
+
+ mutable sync_primitives::Lock state_lock_;
+ // Variable means HMI readiness to provide system time by request
+ volatile bool utc_time_can_be_received_;
+ // Varible used to schedule next GetSystemTime request
+ // if at the moment of sending first GetSystemTime request
+ // HMI is not ready to provide system time
+ volatile bool schedule_request_;
+ // Varible used to store result for GetSystemTime request
+ time_t last_time_;
+
+ sync_primitives::Lock system_time_listener_lock_;
+ utils::SystemTimeListener* system_time_listener_;
+ ApplicationManager& app_manager_;
+};
+
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_SYSTEM_TIME_SYSTEM_TIME_HANDLER_IMPL_H_
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 5edd485343..fac7d596a6 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -1700,6 +1700,10 @@ bool ApplicationManagerImpl::OnHandshakeDone(
return false;
}
+void ApplicationManagerImpl::OnHandshakeFailed() {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
void ApplicationManagerImpl::OnCertificateUpdateRequired() {
LOG4CXX_AUTO_TRACE(logger_);
GetPolicyHandler().OnPTExchangeNeeded();
diff --git a/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_request.cc b/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_request.cc
new file mode 100644
index 0000000000..215b0404a7
--- /dev/null
+++ b/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_request.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribut wiion.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "application_manager/commands/hmi/basic_communication_get_system_time_request.h"
+
+namespace application_manager {
+
+namespace commands {
+
+BasicCommunicationGetSystemTimeRequest::BasicCommunicationGetSystemTimeRequest(
+ const MessageSharedPtr& message, ApplicationManager& application_manager)
+ : RequestToHMI(message, application_manager) {}
+
+void BasicCommunicationGetSystemTimeRequest::onTimeOut() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ application_manager_.protocol_handler().NotifyOnFailedHandshake();
+}
+
+} // namespace commands
+} // namespace application_manager
diff --git a/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_response.cc b/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_response.cc
new file mode 100644
index 0000000000..26dd115d1a
--- /dev/null
+++ b/src/components/application_manager/src/commands/hmi/basic_communication_get_system_time_response.cc
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "application_manager/commands/hmi/basic_communication_get_system_time_response.h"
+#include "utils/logger.h"
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "Commands")
+
+namespace application_manager {
+namespace commands {
+
+BasicCommunicationGetSystemTimeResponse::
+ BasicCommunicationGetSystemTimeResponse(
+ const MessageSharedPtr& message,
+ ApplicationManager& application_manager)
+ : ResponseFromHMI(message, application_manager) {}
+
+void BasicCommunicationGetSystemTimeResponse::Run() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ event_engine::Event event(
+ hmi_apis::FunctionID::BasicCommunication_GetSystemTime);
+ event.set_smart_object(*message_);
+ event.raise(application_manager_.event_dispatcher());
+}
+
+} // namespace commands
+} // namespace application_manager
diff --git a/src/components/application_manager/src/commands/hmi/on_system_time_ready_notification.cc b/src/components/application_manager/src/commands/hmi/on_system_time_ready_notification.cc
new file mode 100644
index 0000000000..d2376e6dfe
--- /dev/null
+++ b/src/components/application_manager/src/commands/hmi/on_system_time_ready_notification.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "application_manager/commands/hmi/on_system_time_ready_notification.h"
+
+#include "application_manager/event_engine/event.h"
+#include "interfaces/HMI_API.h"
+
+namespace application_manager {
+
+namespace commands {
+
+OnSystemTimeReadyNotification::OnSystemTimeReadyNotification(
+ const MessageSharedPtr& message, ApplicationManager& application_manager)
+ : NotificationFromHMI(message, application_manager) {}
+
+OnSystemTimeReadyNotification::~OnSystemTimeReadyNotification() {}
+
+void OnSystemTimeReadyNotification::Run() {
+ event_engine::Event event(
+ hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady);
+ event.set_smart_object(*message_);
+ event.raise(application_manager_.event_dispatcher());
+}
+
+} // namespace commands
+} // namespace application_manager
diff --git a/src/components/application_manager/src/commands/hmi/request_to_hmi.cc b/src/components/application_manager/src/commands/hmi/request_to_hmi.cc
index 6905e7cdef..23c020bca2 100644
--- a/src/components/application_manager/src/commands/hmi/request_to_hmi.cc
+++ b/src/components/application_manager/src/commands/hmi/request_to_hmi.cc
@@ -74,7 +74,9 @@ bool RequestToHMI::CleanUp() {
return true;
}
-void RequestToHMI::Run() {}
+void RequestToHMI::Run() {
+ SendRequest();
+}
void RequestToHMI::SendRequest() {
(*message_)[strings::params][strings::protocol_type] = hmi_protocol_type_;
diff --git a/src/components/application_manager/src/hmi_command_factory.cc b/src/components/application_manager/src/hmi_command_factory.cc
index a7f3ce7e6b..5ef8605999 100644
--- a/src/components/application_manager/src/hmi_command_factory.cc
+++ b/src/components/application_manager/src/hmi_command_factory.cc
@@ -224,6 +224,7 @@
#include "application_manager/commands/hmi/navi_get_way_points_request.h"
#include "application_manager/commands/hmi/navi_get_way_points_response.h"
#include "application_manager/commands/hmi/on_ready_notification.h"
+#include "application_manager/commands/hmi/on_system_time_ready_notification.h"
#include "application_manager/commands/hmi/on_device_chosen_notification.h"
#include "application_manager/commands/hmi/on_file_removed_notification.h"
#include "application_manager/commands/hmi/on_system_context_notification.h"
@@ -269,6 +270,8 @@
#include "application_manager/commands/hmi/on_system_error_notification.h"
#include "application_manager/commands/hmi/basic_communication_system_request.h"
#include "application_manager/commands/hmi/basic_communication_system_response.h"
+#include "application_manager/commands/hmi/basic_communication_get_system_time_request.h"
+#include "application_manager/commands/hmi/basic_communication_get_system_time_response.h"
#include "application_manager/commands/hmi/basic_communication_on_awake_sdl.h"
#include "application_manager/commands/hmi/sdl_policy_update.h"
#include "application_manager/commands/hmi/sdl_policy_update_response.h"
@@ -1285,6 +1288,11 @@ CommandSharedPtr HMICommandFactory::CreateCommand(
new commands::OnReadyNotification(message, application_manager));
break;
}
+ case hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady: {
+ command.reset(new commands::OnSystemTimeReadyNotification(
+ message, application_manager));
+ break;
+ }
case hmi_apis::FunctionID::BasicCommunication_OnDeviceChosen: {
command.reset(new commands::OnDeviceChosenNotification(
message, application_manager));
@@ -2221,6 +2229,16 @@ CommandSharedPtr HMICommandFactory::CreateCommand(
}
break;
}
+ case hmi_apis::FunctionID::BasicCommunication_GetSystemTime: {
+ if (is_response) {
+ command.reset(new commands::BasicCommunicationGetSystemTimeResponse(
+ message, application_manager));
+ } else {
+ command.reset(new commands::BasicCommunicationGetSystemTimeRequest(
+ message, application_manager));
+ }
+ break;
+ }
case hmi_apis::FunctionID::Navigation_SendLocation: {
if (is_response) {
command.reset(new commands::NaviSendLocationResponse(
diff --git a/src/components/application_manager/src/message_helper/message_helper.cc b/src/components/application_manager/src/message_helper/message_helper.cc
index b674a090c0..b854d83c6e 100644
--- a/src/components/application_manager/src/message_helper/message_helper.cc
+++ b/src/components/application_manager/src/message_helper/message_helper.cc
@@ -368,6 +368,20 @@ void MessageHelper::SendDecryptCertificateToHMI(const std::string& file_name,
app_mngr.ManageHMICommand(message);
}
+void MessageHelper::SendGetSystemTimeRequest(const uint32_t correlation_id,
+ ApplicationManager& app_mngr) {
+ using namespace smart_objects;
+ SmartObjectSPtr message =
+ CreateMessageForHMI(hmi_apis::messageType::request, correlation_id);
+
+ DCHECK(message);
+
+ (*message)[strings::params][strings::function_id] =
+ hmi_apis::FunctionID::BasicCommunication_GetSystemTime;
+
+ app_mngr.ManageHMICommand(message);
+}
+
void MessageHelper::SendHashUpdateNotification(const uint32_t app_id,
ApplicationManager& app_mngr) {
LOG4CXX_AUTO_TRACE(logger_);
diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc
index 4d1805d2a5..ac9dd91caf 100644
--- a/src/components/application_manager/src/policies/policy_handler.cc
+++ b/src/components/application_manager/src/policies/policy_handler.cc
@@ -1772,11 +1772,11 @@ void PolicyHandler::OnCertificateDecrypted(bool is_succeeded) {
void PolicyHandler::OnCertificateUpdated(const std::string& certificate_data) {
LOG4CXX_AUTO_TRACE(logger_);
sync_primitives::AutoLock lock(listeners_lock_);
- HandlersCollection::const_iterator it = listeners_.begin();
- for (; it != listeners_.end(); ++it) {
- PolicyHandlerObserver* observer = *it;
- observer->OnCertificateUpdated(certificate_data);
- }
+ std::for_each(
+ listeners_.begin(),
+ listeners_.end(),
+ std::bind2nd(std::mem_fun(&PolicyHandlerObserver::OnCertificateUpdated),
+ certificate_data));
}
#endif // EXTERNAL_PROPRIETARY_MODE
diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc
index a55696524c..e4e89c6e1f 100644
--- a/src/components/application_manager/src/smart_object_keys.cc
+++ b/src/components/application_manager/src/smart_object_keys.cc
@@ -367,7 +367,7 @@ const char* instance_follow_redirect = "InstanceFollowRedirect";
const char* charset = "charset";
const char* content_lenght = "Content_Lenght";
const char* GET = "GET";
-} // http_request
+} // namespace http_request
namespace mobile_notification {
const char* state = "state";
@@ -380,7 +380,17 @@ const char* kFull = "FULL";
const char* kLimited = "LIMITED";
const char* kBackground = "BACKGROUND";
const char* kNone = "NONE";
-}
+} // namespace hmi_levels
+
+namespace time_keys {
+const char* millisecond = "millisecond";
+const char* second = "second";
+const char* minute = "minute";
+const char* hour = "hour";
+const char* day = "day";
+const char* month = "month";
+const char* year = "year";
+} // namespace time_keys
namespace hmi_request {
const char* parent_id = "parentID";
@@ -453,7 +463,7 @@ const char* num_custom_presets_available = "numCustomPresetsAvailable";
const char* urls = "urls";
const char* policy_app_id = "policyAppID";
const char* enabled = "enabled";
-
+const char* system_time = "systemTime";
} // namespace hmi_response
namespace hmi_notification {
@@ -468,7 +478,6 @@ const char* policyfile = "policyfile";
const char* is_active = "isActive";
const char* is_deactivated = "isDeactivated";
const char* event_name = "eventName";
-
} // namespace hmi_notification
} // namespace application_manager
diff --git a/src/components/application_manager/src/system_time/system_time_handler_impl.cc b/src/components/application_manager/src/system_time/system_time_handler_impl.cc
new file mode 100644
index 0000000000..a91fb16197
--- /dev/null
+++ b/src/components/application_manager/src/system_time/system_time_handler_impl.cc
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "application_manager/system_time/system_time_handler_impl.h"
+
+#include <algorithm>
+
+#include "application_manager/message_helper.h"
+#include "application_manager/smart_object_keys.h"
+#include "interfaces/HMI_API.h"
+#include "utils/logger.h"
+
+namespace application_manager {
+
+SystemTimeHandlerImpl::SystemTimeHandlerImpl(
+ ApplicationManager& application_manager)
+ : event_engine::EventObserver(application_manager.event_dispatcher())
+ , utc_time_can_be_received_(false)
+ , schedule_request_(false)
+ , system_time_listener_(NULL)
+ , app_manager_(application_manager) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ subscribe_on_event(
+ hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady);
+}
+
+SystemTimeHandlerImpl::~SystemTimeHandlerImpl() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ unsubscribe_from_all_events();
+}
+
+void SystemTimeHandlerImpl::DoSystemTimeQuery() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ using namespace application_manager;
+
+ sync_primitives::AutoLock lock(state_lock_);
+ if (!utc_time_can_be_received_) {
+ LOG4CXX_INFO(logger_,
+ "Navi module is not yet ready."
+ << "Will process request once it became ready.");
+ schedule_request_ = true;
+ return;
+ }
+ SendTimeRequest();
+}
+
+void SystemTimeHandlerImpl::DoSubscribe(utils::SystemTimeListener* listener) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(listener);
+ sync_primitives::AutoLock lock(system_time_listener_lock_);
+ system_time_listener_ = listener;
+}
+
+void SystemTimeHandlerImpl::DoUnsubscribe(utils::SystemTimeListener* listener) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(system_time_listener_lock_);
+ system_time_listener_ = NULL;
+}
+
+time_t SystemTimeHandlerImpl::FetchSystemTime() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return last_time_;
+}
+
+bool SystemTimeHandlerImpl::utc_time_can_be_received() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(state_lock_);
+ return utc_time_can_be_received_;
+}
+
+void SystemTimeHandlerImpl::SendTimeRequest() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ using namespace application_manager;
+ uint32_t correlation_id = app_manager_.GetNextHMICorrelationID();
+ subscribe_on_event(hmi_apis::FunctionID::BasicCommunication_GetSystemTime,
+ correlation_id);
+ MessageHelper::SendGetSystemTimeRequest(correlation_id, app_manager_);
+}
+
+void SystemTimeHandlerImpl::on_event(
+ const application_manager::event_engine::Event& event) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ using namespace application_manager;
+ using namespace hmi_apis::FunctionID;
+ switch (event.id()) {
+ case BasicCommunication_OnSystemTimeReady:
+ ProcessSystemTimeReadyNotification();
+ break;
+ case BasicCommunication_GetSystemTime:
+ ProcessSystemTimeResponse(event);
+ break;
+ default:
+ LOG4CXX_ERROR(logger_, "Unknown Event received");
+ break;
+ }
+}
+
+void SystemTimeHandlerImpl::ProcessSystemTimeReadyNotification() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(state_lock_);
+ utc_time_can_be_received_ = true;
+ if (schedule_request_) {
+ SendTimeRequest();
+ schedule_request_ = false;
+ }
+ unsubscribe_from_event(
+ hmi_apis::FunctionID::BasicCommunication_OnSystemTimeReady);
+}
+
+void SystemTimeHandlerImpl::ProcessSystemTimeResponse(
+ const application_manager::event_engine::Event& event) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const smart_objects::SmartObject& message = event.smart_object();
+ const smart_objects::SmartObject& system_time_so =
+ message[strings::msg_params][hmi_response::system_time];
+
+ struct tm system_time;
+ memset(&system_time, 0, sizeof(struct tm));
+
+ system_time.tm_sec = system_time_so[time_keys::second].asInt();
+ system_time.tm_min = system_time_so[time_keys::minute].asInt();
+ // According to tm specification of tm type hour should be decreased by 1
+ system_time.tm_hour = system_time_so[time_keys::hour].asInt() - 1;
+ system_time.tm_mday = system_time_so[time_keys::day].asInt();
+ // According to tm specification of tm type mon should be decreased by 1
+ system_time.tm_mon = system_time_so[time_keys::month].asInt() - 1;
+ // According to tm specification of tm type
+ // tm_year - number of years since 1900
+ system_time.tm_year = system_time_so[time_keys::year].asInt() - 1900;
+
+ // Normalize and convert time from 'tm' format to 'time_t'
+ last_time_ = mktime(&system_time);
+
+ sync_primitives::AutoLock lock(system_time_listener_lock_);
+ if (system_time_listener_) {
+ system_time_listener_->OnSystemTimeArrived(last_time_);
+ }
+}
+
+} // namespace application_manager
diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc
index 5b26304302..b97c6eacd4 100644
--- a/src/components/connection_handler/src/connection_handler_impl.cc
+++ b/src/components/connection_handler/src/connection_handler_impl.cc
@@ -316,6 +316,7 @@ void ConnectionHandlerImpl::RemoveConnection(
bool AllowProtection(const ConnectionHandlerSettings& settings,
const protocol_handler::ServiceType& service_type,
const bool is_protected) {
+ LOG4CXX_AUTO_TRACE(logger_);
const std::vector<int>& force_unprotected_list =
is_protected ? settings.force_unprotected_service()
: settings.force_protected_service();
diff --git a/src/components/include/policy/policy_regular/policy/policy_manager.h b/src/components/include/policy/policy_regular/policy/policy_manager.h
index 84d48a691e..634892ea15 100644
--- a/src/components/include/policy/policy_regular/policy/policy_manager.h
+++ b/src/components/include/policy/policy_regular/policy/policy_manager.h
@@ -531,6 +531,12 @@ class PolicyManager : public usage_statistics::StatisticsManager {
virtual bool HasCertificate() const = 0;
/**
+ * @brief Sets decrypted certificate in policy table
+ * @param certificate content of certificate
+ */
+ virtual void SetDecryptedCertificate(const std::string& certificate) = 0;
+
+ /**
* @brief Getter for policy settings
* @return policy settings instance
*/
diff --git a/src/components/include/protocol_handler/protocol_handler.h b/src/components/include/protocol_handler/protocol_handler.h
index 6aafd7d53f..1da8d61e52 100644
--- a/src/components/include/protocol_handler/protocol_handler.h
+++ b/src/components/include/protocol_handler/protocol_handler.h
@@ -103,6 +103,12 @@ class ProtocolHandler {
virtual void SendEndService(int32_t connection_id,
uint8_t session_id,
uint8_t service_type) = 0;
+
+ /**
+ * \brief Called to notify all handsheke handlers about handshake failure.
+ */
+ virtual void NotifyOnFailedHandshake() = 0;
+
/**
* \brief Protocol handler settings getter
* \return pointer to protocol handler settings class
diff --git a/src/components/include/security_manager/crypto_manager.h b/src/components/include/security_manager/crypto_manager.h
index 18c06ffe06..486b6da64f 100644
--- a/src/components/include/security_manager/crypto_manager.h
+++ b/src/components/include/security_manager/crypto_manager.h
@@ -33,6 +33,7 @@
#ifndef SRC_COMPONENTS_INCLUDE_SECURITY_MANAGER_CRYPTO_MANAGER_H_
#define SRC_COMPONENTS_INCLUDE_SECURITY_MANAGER_CRYPTO_MANAGER_H_
+#include <time.h>
#include "application_manager/policies/policy_handler_observer.h"
#include "security_manager/security_manager_settings.h"
@@ -65,8 +66,16 @@ class CryptoManager : public policy::PolicyHandlerObserver {
virtual bool OnCertificateUpdated(const std::string& data) = 0;
virtual void ReleaseSSLContext(SSLContext* context) = 0;
virtual std::string LastError() const = 0;
-
- virtual bool IsCertificateUpdateRequired() const = 0;
+ /**
+ * @brief IsCertificateUpdateRequired checks if certificate update is needed
+ * @param system_time - time with which certificate expiration time
+ * should be compared
+ * @param certificates_time - certificate expiration time
+ * @return True if certificate expired and need to be updated
+ * otherwise False
+ */
+ virtual bool IsCertificateUpdateRequired(
+ const time_t system_time, const time_t certificates_time) const = 0;
/**
* \brief Crypto manager settings getter
* \return pointer to crypto manager settings class
diff --git a/src/components/include/security_manager/security_manager.h b/src/components/include/security_manager/security_manager.h
index 8f772f6a13..6ad5e96989 100644
--- a/src/components/include/security_manager/security_manager.h
+++ b/src/components/include/security_manager/security_manager.h
@@ -41,6 +41,7 @@
#include "protocol_handler/session_observer.h"
#include "security_manager/security_manager_listener.h"
+#include "application_manager/policies/policy_handler_observer.h"
namespace security_manager {
@@ -50,7 +51,8 @@ class CryptoManager;
* protocol_handler::ProtocolObserver
* and provide interface for handling Security queries from mobile side
*/
-class SecurityManager : public protocol_handler::ProtocolObserver {
+class SecurityManager : public protocol_handler::ProtocolObserver,
+ public policy::PolicyHandlerObserver {
public:
/**
* \brief InternalErrors is 1 byte identifier of internal error
@@ -70,6 +72,10 @@ class SecurityManager : public protocol_handler::ProtocolObserver {
ERROR_INTERNAL = 0xFF,
ERROR_UNKNOWN_INTERNAL_ERROR = 0xFE // error value for testing
};
+
+ // SSL context creation strategy
+ enum ContextCreationStrategy { kUseExisting = 0, kForceRecreation };
+
/**
* \brief Sets pointer for Connection Handler layer for managing sessions
* \param session_observer pointer to object of the class implementing
@@ -114,13 +120,15 @@ class SecurityManager : public protocol_handler::ProtocolObserver {
}
/**
- * \brief Create new SSLContext for connection or return exists
+ * @brief Create new SSLContext for connection or return exists
* Do not notify listeners, send security error on occure
- * \param connection_key Unique key used by other components as session
+ * @param connection_key Unique key used by other components as session
* identifier
+ * @param cc_strategy - SSL context creation strategy
* @return new \c SSLContext or \c NULL on any error
*/
- virtual SSLContext* CreateSSLContext(const uint32_t& connection_key) = 0;
+ virtual SSLContext* CreateSSLContext(const uint32_t& connection_key,
+ ContextCreationStrategy cc_strategy) = 0;
/**
* \brief Start handshake as SSL client
@@ -128,10 +136,26 @@ class SecurityManager : public protocol_handler::ProtocolObserver {
virtual void StartHandshake(uint32_t connection_key) = 0;
/**
+ * @brief PostponeHandshake allows to postpone handshake. It notifies
+ * cryptomanager that certificate should be updated and adds specified
+ * connection key to the list of the certificate awaiting connections.
+ * @param connection_key the identifier for connection to postpone handshake.
+ */
+ virtual void PostponeHandshake(const uint32_t connection_key) = 0;
+
+ /**
* @brief Check whether certificate should be updated
+ * @param connection_key the connection identifier to check certificate for.
* @return true if certificate should be updated otherwise false
*/
- virtual bool IsCertificateUpdateRequired() = 0;
+ virtual bool IsCertificateUpdateRequired(const uint32_t connection_key) = 0;
+
+ /**
+ * @brief Checks whether system time ready notification
+ * was received from hmi
+ * @return true if received otherwise false
+ */
+ virtual bool IsSystemTimeProviderReady() const = 0;
/**
* @brief Notify all listeners that certificate update required
@@ -150,6 +174,18 @@ class SecurityManager : public protocol_handler::ProtocolObserver {
*/
virtual void AddListener(SecurityManagerListener* const listener) = 0;
virtual void RemoveListener(SecurityManagerListener* const listener) = 0;
+
+ /**
+ * @brief OnCertificateUpdated allows to obtain notification when certificate
+ * has been updated with policy table update. Pass this certificate to crypto
+ * manager for further processing. Also process postopnes handshake for the
+ * certain connection key.
+ *
+ * @param data the certificates content.
+ *
+ * @return always true.
+ */
+ virtual bool OnCertificateUpdated(const std::string& data) = 0;
};
} // namespace security_manager
#endif // SRC_COMPONENTS_INCLUDE_SECURITY_MANAGER_SECURITY_MANAGER_H_
diff --git a/src/components/include/security_manager/security_manager_listener.h b/src/components/include/security_manager/security_manager_listener.h
index aeb3334a56..5942839b58 100644
--- a/src/components/include/security_manager/security_manager_listener.h
+++ b/src/components/include/security_manager/security_manager_listener.h
@@ -47,6 +47,12 @@ class SecurityManagerListener {
*/
virtual bool OnHandshakeDone(uint32_t connection_key,
SSLContext::HandshakeResult result) = 0;
+
+ /**
+ * @brief Notification about handshake failure
+ */
+ virtual void OnHandshakeFailed() = 0;
+
/**
* @brief Notify listeners that certificate update is required.
*/
diff --git a/src/components/include/security_manager/ssl_context.h b/src/components/include/security_manager/ssl_context.h
index 86997edbd9..9d66e1af2f 100644
--- a/src/components/include/security_manager/ssl_context.h
+++ b/src/components/include/security_manager/ssl_context.h
@@ -81,10 +81,11 @@ class SSLContext {
HandshakeContext(const custom_str::CustomString& exp_sn,
const custom_str::CustomString& exp_cn)
- : expected_sn(exp_sn), expected_cn(exp_cn) {}
+ : expected_sn(exp_sn), expected_cn(exp_cn), system_time(time(NULL)) {}
custom_str::CustomString expected_sn;
custom_str::CustomString expected_cn;
+ time_t system_time;
};
virtual HandshakeResult StartHandshake(const uint8_t** const out_data,
@@ -103,6 +104,14 @@ class SSLContext {
size_t* out_data_size) = 0;
virtual bool IsInitCompleted() const = 0;
virtual bool IsHandshakePending() const = 0;
+ /**
+ * @brief GetCertificateDueDate gets certificate expiration date
+ * @param due_date - certificate expiration time to be received
+ * @return True if certificate expiration date received
+ * otherwise False
+ */
+ virtual bool GetCertificateDueDate(time_t& due_date) const = 0;
+ virtual bool HasCertificate() const = 0;
virtual size_t get_max_block_size(size_t mtu) const = 0;
virtual std::string LastError() const = 0;
diff --git a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h
index cf20dcb666..e68c0ba0c3 100644
--- a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h
+++ b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h
@@ -206,7 +206,7 @@ class MockCacheManagerInterface : public CacheManagerInterface {
MOCK_METHOD1(GetHMITypes,
const policy_table::AppHMITypes*(const std::string& app_id));
MOCK_CONST_METHOD0(GetCertificate, std::string());
- MOCK_METHOD1(SetDecryptedCertificate, void(const std::string&));
+ MOCK_CONST_METHOD1(SetDecryptedCertificate, void(const std::string&));
MOCK_METHOD1(GetGroups, const policy_table::Strings&(const PTString& app_id));
MOCK_CONST_METHOD2(AppHasHMIType,
bool(const std::string& application_id,
diff --git a/src/components/include/test/protocol_handler/mock_protocol_handler.h b/src/components/include/test/protocol_handler/mock_protocol_handler.h
index 79c2188cdf..e667911944 100644
--- a/src/components/include/test/protocol_handler/mock_protocol_handler.h
+++ b/src/components/include/test/protocol_handler/mock_protocol_handler.h
@@ -72,6 +72,7 @@ class MockProtocolHandler : public ::protocol_handler::ProtocolHandler {
MOCK_METHOD2(NotifySessionStarted,
void(const ::protocol_handler::SessionContext& context,
std::vector<std::string>& rejected_params));
+ MOCK_METHOD0(NotifyOnFailedHandshake, void());
};
} // namespace protocol_handler_test
} // namespace components
diff --git a/src/components/include/test/security_manager/mock_crypto_manager.h b/src/components/include/test/security_manager/mock_crypto_manager.h
index 55c364bd89..61ec5183e4 100644
--- a/src/components/include/test/security_manager/mock_crypto_manager.h
+++ b/src/components/include/test/security_manager/mock_crypto_manager.h
@@ -52,7 +52,9 @@ class MockCryptoManager : public ::security_manager::CryptoManager {
MOCK_METHOD0(CreateSSLContext, ::security_manager::SSLContext*());
MOCK_METHOD1(ReleaseSSLContext, void(::security_manager::SSLContext*));
MOCK_CONST_METHOD0(LastError, std::string());
- MOCK_CONST_METHOD0(IsCertificateUpdateRequired, bool());
+ MOCK_CONST_METHOD2(IsCertificateUpdateRequired,
+ bool(const time_t system_time,
+ const time_t certificates_time));
};
} // namespace security_manager_test
} // namespace components
diff --git a/src/components/include/test/security_manager/mock_security_manager.h b/src/components/include/test/security_manager/mock_security_manager.h
index 11890cb071..153ce85422 100644
--- a/src/components/include/test/security_manager/mock_security_manager.h
+++ b/src/components/include/test/security_manager/mock_security_manager.h
@@ -54,8 +54,9 @@ class MockSecurityManager : public ::security_manager::SecurityManager {
MOCK_METHOD4(
SendInternalError,
void(const uint32_t, const uint8_t&, const std::string&, const uint32_t));
- MOCK_METHOD1(CreateSSLContext,
- ::security_manager::SSLContext*(const uint32_t&));
+ MOCK_METHOD2(CreateSSLContext,
+ ::security_manager::SSLContext*(const uint32_t&,
+ ContextCreationStrategy));
MOCK_METHOD1(StartHandshake, void(uint32_t));
MOCK_METHOD1(AddListener, void(::security_manager::SecurityManagerListener*));
MOCK_METHOD1(RemoveListener,
@@ -65,9 +66,12 @@ class MockSecurityManager : public ::security_manager::SecurityManager {
void(const ::protocol_handler::RawMessagePtr));
MOCK_METHOD1(OnMobileMessageSent,
void(const ::protocol_handler::RawMessagePtr));
- MOCK_METHOD0(IsCertificateUpdateRequired, bool());
+ MOCK_METHOD1(IsCertificateUpdateRequired, bool(const uint32_t));
MOCK_METHOD0(NotifyOnCertificateUpdateRequired, void());
MOCK_METHOD0(IsPolicyCertificateDataEmpty, bool());
+ MOCK_METHOD1(OnCertificateUpdated, bool(const std::string&));
+ MOCK_METHOD1(PostponeHandshake, void(const uint32_t));
+ MOCK_CONST_METHOD0(IsSystemTimeProviderReady, bool());
};
/*
diff --git a/src/components/include/test/security_manager/mock_security_manager_listener.h b/src/components/include/test/security_manager/mock_security_manager_listener.h
index a06762a09d..76273b244d 100644
--- a/src/components/include/test/security_manager/mock_security_manager_listener.h
+++ b/src/components/include/test/security_manager/mock_security_manager_listener.h
@@ -49,6 +49,7 @@ class MockSecurityManagerListener
::security_manager::SSLContext::HandshakeResult result));
MOCK_METHOD0(OnCertificateUpdateRequired, void());
MOCK_CONST_METHOD1(GetPolicyCertificateData, bool(std::string& data));
+ MOCK_METHOD0(OnHandshakeFailed, void());
};
} // namespace security_manager_test
} // namespace components
diff --git a/src/components/include/test/security_manager/mock_ssl_context.h b/src/components/include/test/security_manager/mock_ssl_context.h
index 6b6a26a226..02198d1d22 100644
--- a/src/components/include/test/security_manager/mock_ssl_context.h
+++ b/src/components/include/test/security_manager/mock_ssl_context.h
@@ -68,6 +68,8 @@ class MockSSLContext : public ::security_manager::SSLContext {
MOCK_CONST_METHOD0(LastError, std::string());
MOCK_METHOD0(ResetConnection, void());
MOCK_METHOD1(SetHandshakeContext, void(const HandshakeContext& hsh_ctx));
+ MOCK_CONST_METHOD0(HasCertificate, bool());
+ MOCK_CONST_METHOD1(GetCertificateDueDate, bool(time_t& due_date));
};
} // namespace security_manager_test
} // namespace components
diff --git a/src/components/include/test/utils/mock_system_time_handler.h b/src/components/include/test/utils/mock_system_time_handler.h
new file mode 100644
index 0000000000..ef80e698f5
--- /dev/null
+++ b/src/components/include/test/utils/mock_system_time_handler.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_INCLUDE_TEST_SECURITY_MANAGER_MOCK_SYSTEM_TIME_HANDLER_H
+#define SRC_COMPONENTS_INCLUDE_TEST_SECURITY_MANAGER_MOCK_SYSTEM_TIME_HANDLER_H
+
+#include "gmock/gmock.h"
+#include "utils/system_time_handler.h"
+
+namespace test {
+namespace components {
+namespace security_manager_test {
+
+class MockSystemTimeHandler : public ::utils::SystemTimeHandler {
+ public:
+ MockSystemTimeHandler() {}
+ MOCK_METHOD0(QuerySystemTime, void());
+ MOCK_METHOD1(SubscribeOnSystemTime,
+ void(utils::SystemTimeListener* listener));
+ MOCK_METHOD1(UnSubscribeFromSystemTime,
+ void(utils::SystemTimeListener* listener));
+ MOCK_METHOD0(GetUTCTime, time_t());
+ MOCK_CONST_METHOD0(system_time_can_be_received, bool());
+ ~MockSystemTimeHandler() {}
+
+ private:
+ void DoSubscribe(utils::SystemTimeListener*) {}
+ void DoSystemTimeQuery() {}
+ void DoUnsubscribe(utils::SystemTimeListener* listener) {}
+ bool utc_time_can_be_received() const {
+ return true;
+ }
+ time_t FetchSystemTime() {
+ return 0;
+ }
+};
+} // namespace security_manager_test
+} // namespace components
+} // namespace test
+#endif // SRC_COMPONENTS_INCLUDE_TEST_SECURITY_MANAGER_MOCK_SYSTEM_TIME_HANDLER_H
diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml
index 0281b50956..ac623ee021 100644
--- a/src/components/interfaces/HMI_API.xml
+++ b/src/components/interfaces/HMI_API.xml
@@ -2854,6 +2854,16 @@
</interface>
<interface name="BasicCommunication" version="1.2.1" date="2017-08-02">
+ <function name="GetSystemTime" messagetype="request">
+ <description> Allows to obtain current sytem time</description>
+ </function>
+ <function name="GetSystemTime" messagetype="response">
+ <param name="systemTime" type="Common.DateTime" mandatory="true">
+ </param>
+ </function>
+ <function name="OnSystemTimeReady" messagetype="notification">
+ <description>HMI notifies SDL with this notification that NAVI module is ready to provide system time.</description>
+ </function>
<function name="OnReady" messagetype="notification">
<description>HMI must notify SDL about its readiness to start communication. In fact, this has to be the first message between SDL and HMI.</description>
</function>
diff --git a/src/components/policy/policy_regular/include/policy/cache_manager.h b/src/components/policy/policy_regular/include/policy/cache_manager.h
index 4a0a09db83..47ab0d4298 100644
--- a/src/components/policy/policy_regular/include/policy/cache_manager.h
+++ b/src/components/policy/policy_regular/include/policy/cache_manager.h
@@ -296,6 +296,12 @@ class CacheManager : public CacheManagerInterface {
bool IsDefaultPolicy(const std::string& app_id) const OVERRIDE;
/**
+ * @brief Sets decrypted certificate in policy table
+ * @param certificate content of certificate
+ */
+ void SetDecryptedCertificate(const std::string& certificate) const OVERRIDE;
+
+ /**
* @brief SetIsDefault Sets is_default flag for application
* @param app_id app specific application
* @return true in case opperation was done successfully.
diff --git a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h
index 3dd2953865..477ad6b3ca 100644
--- a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h
+++ b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h
@@ -303,6 +303,13 @@ class CacheManagerInterface {
virtual bool IsDefaultPolicy(const std::string& app_id) const = 0;
/**
+ * @brief Sets decrypted certificate in policy table
+ * @param certificate content of certificate
+ */
+ virtual void SetDecryptedCertificate(
+ const std::string& certificate) const = 0;
+
+ /**
* @brief SetIsDefault Sets is_default flag for application
* @param app_id app specific application
* @return true in case opperation was done successfully.
diff --git a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h
index 8379cf4d82..d768e7acdc 100644
--- a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h
+++ b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h
@@ -594,6 +594,8 @@ class PolicyManagerImpl : public PolicyManager {
*/
bool HasCertificate() const OVERRIDE;
+ void SetDecryptedCertificate(const std::string& certificate) OVERRIDE;
+
/**
* @brief Finds the next URL that must be sent on OnSystemRequest retry
* @param urls vector of vectors that contain urls for each application
diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc
index 1d51b81af4..5cefbe2c17 100644
--- a/src/components/policy/policy_regular/src/cache_manager.cc
+++ b/src/components/policy/policy_regular/src/cache_manager.cc
@@ -1291,6 +1291,13 @@ bool CacheManager::IsDefaultPolicy(const std::string& app_id) const {
return result;
}
+void CacheManager::SetDecryptedCertificate(
+ const std::string& certificate) const {
+ CACHE_MANAGER_CHECK_VOID();
+ sync_primitives::AutoLock auto_lock(cache_lock_);
+ *pt_->policy_table.module_config.certificate = certificate;
+}
+
bool CacheManager::SetIsDefault(const std::string& app_id) {
CACHE_MANAGER_CHECK(false);
sync_primitives::AutoLock auto_lock(cache_lock_);
diff --git a/src/components/policy/policy_regular/src/policy_manager_impl.cc b/src/components/policy/policy_regular/src/policy_manager_impl.cc
index a48a9a1ba0..7c6c1173f0 100644
--- a/src/components/policy/policy_regular/src/policy_manager_impl.cc
+++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc
@@ -1046,6 +1046,13 @@ bool PolicyManagerImpl::HasCertificate() const {
return !cache_->GetCertificate().empty();
}
+void PolicyManagerImpl::SetDecryptedCertificate(
+ const std::string& certificate) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ cache_->SetDecryptedCertificate(certificate);
+ cache_->Backup();
+}
+
class CallStatusChange : public utils::Callable {
public:
CallStatusChange(UpdateStatusManager& upd_manager,
diff --git a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h
index 0ef40290f2..5d536eebad 100644
--- a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h
+++ b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h
@@ -90,6 +90,13 @@ class HandshakeHandler : public security_manager::SecurityManagerListener {
security_manager::SSLContext::HandshakeResult result) OVERRIDE;
/**
+ * @brief Notification about handshake failure
+ * Gets parameters from payload and processes
+ * handshake failure procedure
+ */
+ void OnHandshakeFailed() OVERRIDE;
+
+ /**
* @brief Notification that certificate update is required.
*/
void OnCertificateUpdateRequired() OVERRIDE;
diff --git a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h
index 0efb81cdd7..4d86a78688 100644
--- a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h
+++ b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h
@@ -235,6 +235,8 @@ class ProtocolHandlerImpl
uint8_t session_id,
uint8_t service_type);
+ void NotifyOnFailedHandshake() OVERRIDE;
+
// TODO(Ezamakhov): move Ack/Nack as interface for StartSessionHandler
/**
* \brief Sends acknowledgement of starting session to mobile application
@@ -686,7 +688,9 @@ class ProtocolHandlerImpl
bool is_ptu_triggered_;
std::list<std::shared_ptr<HandshakeHandler> > ptu_pending_handlers_;
+ std::list<std::shared_ptr<HandshakeHandler> > handshake_handlers_;
sync_primitives::Lock ptu_handlers_lock_;
+ sync_primitives::Lock handshake_handlers_lock_;
#endif // ENABLE_SECURITY
// Thread that pumps non-parsed messages coming from mobile side.
diff --git a/src/components/protocol_handler/src/handshake_handler.cc b/src/components/protocol_handler/src/handshake_handler.cc
index 055ff2cf45..74987ac2bd 100644
--- a/src/components/protocol_handler/src/handshake_handler.cc
+++ b/src/components/protocol_handler/src/handshake_handler.cc
@@ -92,6 +92,17 @@ bool HandshakeHandler::GetPolicyCertificateData(std::string& data) const {
void HandshakeHandler::OnCertificateUpdateRequired() {}
+void HandshakeHandler::OnHandshakeFailed() {
+ BsonObject params;
+ if (payload_) {
+ params = bson_object_from_bytes(payload_.get());
+ } else {
+ bson_object_initialize_default(&params);
+ }
+ ProcessFailedHandshake(params);
+ bson_object_deinitialize(&params);
+}
+
bool HandshakeHandler::OnHandshakeDone(
uint32_t connection_key,
security_manager::SSLContext::HandshakeResult result) {
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc
index 762b986782..dcb7999ef9 100644
--- a/src/components/protocol_handler/src/protocol_handler_impl.cc
+++ b/src/components/protocol_handler/src/protocol_handler_impl.cc
@@ -149,6 +149,7 @@ ProtocolHandlerImpl::~ProtocolHandlerImpl() {
"Not all observers have unsubscribed"
" from ProtocolHandlerImpl");
}
+ handshake_handlers_.clear();
}
void ProtocolHandlerImpl::AddProtocolObserver(ProtocolObserver* observer) {
@@ -839,6 +840,18 @@ void ProtocolHandlerImpl::OnConnectionClosed(
multiframe_builder_.RemoveConnection(connection_id);
}
+void ProtocolHandlerImpl::NotifyOnFailedHandshake() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(handshake_handlers_lock_);
+
+ std::for_each(
+ handshake_handlers_.begin(),
+ handshake_handlers_.end(),
+ std::bind(&HandshakeHandler::OnHandshakeFailed, std::placeholders::_1));
+
+ handshake_handlers_.clear();
+}
+
void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -851,12 +864,14 @@ void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) {
return;
}
- const bool is_cert_expired = security_manager_->IsCertificateUpdateRequired();
for (auto handler : ptu_pending_handlers_) {
+ const bool is_cert_expired = security_manager_->IsCertificateUpdateRequired(
+ handler->connection_key());
security_manager::SSLContext* ssl_context =
- is_cert_expired
- ? NULL
- : security_manager_->CreateSSLContext(handler->connection_key());
+ is_cert_expired ? NULL
+ : security_manager_->CreateSSLContext(
+ handler->connection_key(),
+ security_manager::SecurityManager::kUseExisting);
if (!ssl_context) {
const std::string error("CreateSSLContext failed");
@@ -1286,7 +1301,8 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession(
session_observer_.KeyFromPair(connection_id, session_id);
security_manager::SSLContext* ssl_context =
- security_manager_->CreateSSLContext(connection_key);
+ security_manager_->CreateSSLContext(
+ connection_key, security_manager::SecurityManager::kUseExisting);
if (!ssl_context) {
const std::string error("CreateSSLContext failed");
LOG4CXX_ERROR(logger_, error);
@@ -1563,14 +1579,11 @@ void ProtocolHandlerImpl::NotifySessionStarted(
context,
packet->protocol_version(),
bson_object_bytes);
+ handshake_handlers_.push_back(handler);
const bool is_certificate_empty =
security_manager_->IsPolicyCertificateDataEmpty();
- const bool is_certificate_expired =
- is_certificate_empty ||
- security_manager_->IsCertificateUpdateRequired();
-
if (context.is_ptu_required_ && is_certificate_empty) {
LOG4CXX_DEBUG(logger_,
"PTU for StartSessionHandler "
@@ -1586,6 +1599,7 @@ void ProtocolHandlerImpl::NotifySessionStarted(
ptu_pending_handlers_.push_back(handler);
is_ptu_triggered_ = true;
security_manager_->NotifyOnCertificateUpdateRequired();
+ security_manager_->PostponeHandshake(connection_key);
} else {
LOG4CXX_DEBUG(logger_, "PTU has been triggered. Added to pending.");
ptu_pending_handlers_.push_back(handler);
@@ -1594,9 +1608,11 @@ void ProtocolHandlerImpl::NotifySessionStarted(
}
security_manager::SSLContext* ssl_context =
- is_certificate_expired
+ is_certificate_empty
? NULL
- : security_manager_->CreateSSLContext(connection_key);
+ : security_manager_->CreateSSLContext(
+ connection_key,
+ security_manager::SecurityManager::kUseExisting);
if (!ssl_context) {
const std::string error("CreateSSLContext failed");
LOG4CXX_ERROR(logger_, error);
@@ -1630,10 +1646,18 @@ void ProtocolHandlerImpl::NotifySessionStarted(
*fullVersion,
*start_session_ack_params);
} else {
+ LOG4CXX_DEBUG(logger_, "Adding Handshake handler to listenets:");
security_manager_->AddListener(new HandshakeHandler(*handler));
if (!ssl_context->IsHandshakePending()) {
// Start handshake process
security_manager_->StartHandshake(connection_key);
+ if (!security_manager_->IsSystemTimeProviderReady()) {
+ SendStartSessionNAck(context.connection_id_,
+ packet->session_id(),
+ protocol_version,
+ packet->service_type(),
+ rejected_params);
+ }
}
}
LOG4CXX_DEBUG(logger_,
diff --git a/src/components/protocol_handler/test/protocol_handler_tm_test.cc b/src/components/protocol_handler/test/protocol_handler_tm_test.cc
index 8525b1c5b9..075b332345 100644
--- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc
+++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc
@@ -46,6 +46,7 @@
#include "security_manager/mock_ssl_context.h"
#endif // ENABLE_SECURITY
#include "transport_manager/mock_transport_manager.h"
+#include "utils/mock_system_time_handler.h"
#include "utils/make_shared.h"
#include "utils/test_async_waiter.h"
#include <bson_object.h>
@@ -95,8 +96,12 @@ using protocol_handler::kBulk;
using protocol_handler::kInvalidServiceType;
// For TM states
using transport_manager::TransportManagerListener;
+using test::components::security_manager_test::MockSystemTimeHandler;
using transport_manager::E_SUCCESS;
using transport_manager::DeviceInfo;
+// For security
+using ContextCreationStrategy =
+ security_manager::SecurityManager::ContextCreationStrategy;
// For CH entities
using connection_handler::DeviceHandle;
// Google Testing Framework Entities
@@ -987,7 +992,10 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) {
SetProtocolVersion2();
// Expect start protection for unprotected session
- EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key))
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key,
+ security_manager::SecurityManager::
+ ContextCreationStrategy::kUseExisting))
.
// Return fail protection
WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), ReturnNull()));
@@ -1042,7 +1050,7 @@ TEST_F(ProtocolHandlerImplTest,
SetProtocolVersion2();
// call new SSLContext creation
- EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key))
+ EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _))
.
// Return new SSLContext
WillOnce(
@@ -1119,7 +1127,7 @@ TEST_F(ProtocolHandlerImplTest,
.WillOnce(ReturnRefOfCopy(services));
// call new SSLContext creation
- EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key))
+ EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _))
.
// Return new SSLContext
WillOnce(Return(&ssl_context_mock));
@@ -1198,7 +1206,7 @@ TEST_F(ProtocolHandlerImplTest,
times++;
// call new SSLContext creation
- EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key))
+ EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _))
.
// Return new SSLContext
WillOnce(
@@ -1296,7 +1304,7 @@ TEST_F(
times++;
// call new SSLContext creation
- EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key))
+ EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key, _))
.
// Return new SSLContext
WillOnce(
@@ -1392,7 +1400,10 @@ TEST_F(ProtocolHandlerImplTest,
times++;
// call new SSLContext creation
- EXPECT_CALL(security_manager_mock, CreateSSLContext(connection_key))
+ EXPECT_CALL(security_manager_mock,
+ CreateSSLContext(connection_key,
+ security_manager::SecurityManager::
+ ContextCreationStrategy::kUseExisting))
.
// Return new SSLContext
WillOnce(
@@ -1420,27 +1431,37 @@ TEST_F(ProtocolHandlerImplTest,
// Expect add listener for handshake result
EXPECT_CALL(security_manager_mock, AddListener(_))
- // Emulate handshake fail
- .WillOnce(Invoke(OnHandshakeDoneFunctor(
- connection_key,
- security_manager::SSLContext::Handshake_Result_Success)));
+ // Emulate handshake
+ .WillOnce(
+ DoAll(NotifyTestAsyncWaiter(&waiter),
+ Invoke(OnHandshakeDoneFunctor(
+ connection_key,
+ security_manager::SSLContext::Handshake_Result_Success))));
+ times++;
// Listener check SSLContext
EXPECT_CALL(session_observer_mock,
GetSSLContext(connection_key, start_service))
.
// Emulate protection for service is not enabled
- WillOnce(ReturnNull());
+ WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), ReturnNull()));
+ times++;
+
+ EXPECT_CALL(security_manager_mock, IsSystemTimeProviderReady())
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(true)));
+ times++;
- // Expect service protection enable
EXPECT_CALL(session_observer_mock,
- SetProtectionFlag(connection_key, start_service));
+ SetProtectionFlag(connection_key, start_service))
+ .WillOnce(NotifyTestAsyncWaiter(&waiter));
+ times++;
- // Expect send Ack with PROTECTION_OFF (on fail handshake)
+ // Expect send Ack with PROTECTION_ON (on successfull handshake)
EXPECT_CALL(transport_manager_mock,
SendMessageToDevice(
ControlMessage(FRAME_DATA_START_SERVICE_ACK, PROTECTION_ON)))
.WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+
times++;
SendControlMessage(
diff --git a/src/components/security_manager/include/security_manager/crypto_manager_impl.h b/src/components/security_manager/include/security_manager/crypto_manager_impl.h
index 4e48858e5c..c31e02cf48 100644
--- a/src/components/security_manager/include/security_manager/crypto_manager_impl.h
+++ b/src/components/security_manager/include/security_manager/crypto_manager_impl.h
@@ -71,6 +71,8 @@ class CryptoManagerImpl : public CryptoManager {
size_t* out_data_size) OVERRIDE;
bool IsInitCompleted() const OVERRIDE;
bool IsHandshakePending() const OVERRIDE;
+ bool GetCertificateDueDate(time_t& due_date) const OVERRIDE;
+ bool HasCertificate() const OVERRIDE;
size_t get_max_block_size(size_t mtu) const OVERRIDE;
std::string LastError() const OVERRIDE;
void ResetConnection() OVERRIDE;
@@ -101,6 +103,22 @@ class CryptoManagerImpl : public CryptoManager {
std::string GetTextBy(X509_NAME* name, int object) const;
+ /**
+ * @brief Pulls number stored in buffer of chars
+ * and returns it as integer
+ * @param buf where symbols stored
+ * @param idx index of required char to be converted
+ * @return number in integer representation
+ */
+ int get_number_from_char_buf(char* buf, int* idx) const;
+ /**
+ * @brief Converts time from ASN1 format (used in OpenSSL)
+ * to time_t data type
+ * @param time_to_convert time to be converted
+ * @return time in time_t format
+ */
+ time_t convert_asn1_time_to_time_t(ASN1_TIME* time_to_convert) const;
+
SSL* connection_;
BIO* bioIn_;
BIO* bioOut_;
@@ -128,15 +146,13 @@ class CryptoManagerImpl : public CryptoManager {
SSLContext* CreateSSLContext() OVERRIDE;
void ReleaseSSLContext(SSLContext* context) OVERRIDE;
std::string LastError() const OVERRIDE;
- virtual bool IsCertificateUpdateRequired() const OVERRIDE;
+ bool IsCertificateUpdateRequired(
+ const time_t system_time, const time_t certificates_time) const OVERRIDE;
virtual const CryptoManagerSettings& get_settings() const OVERRIDE;
private:
bool set_certificate(const std::string& cert_data);
- int pull_number_from_buf(char* buf, int* idx);
- void asn1_time_to_tm(ASN1_TIME* time);
-
/**
* @brief Sets initial certificate datetime
*/
diff --git a/src/components/security_manager/include/security_manager/security_manager_impl.h b/src/components/security_manager/include/security_manager/security_manager_impl.h
index 469b97d1e1..ab093cc576 100644
--- a/src/components/security_manager/include/security_manager/security_manager_impl.h
+++ b/src/components/security_manager/include/security_manager/security_manager_impl.h
@@ -35,6 +35,8 @@
#include <list>
#include <string>
+#include <set>
+#include <memory>
#include "utils/macro.h"
#include "utils/message_queue.h"
@@ -44,6 +46,7 @@
#include "security_manager/security_query.h"
#include "protocol_handler/protocol_handler.h"
#include "protocol/common.h"
+#include "utils/system_time_handler.h"
namespace security_manager {
/**
@@ -67,12 +70,21 @@ typedef threads::MessageLoopThread<SecurityMessageQueue> SecurityMessageLoop;
* \brief SecurityManagerImpl class implements SecurityManager interface
*/
class SecurityManagerImpl : public SecurityManager,
- public SecurityMessageLoop::Handler {
+ public SecurityMessageLoop::Handler,
+ public utils::SystemTimeListener {
public:
/**
* \brief Constructor
+ * \param system_time_handler allows to work with system time.
*/
- SecurityManagerImpl();
+ explicit SecurityManagerImpl(
+ std::unique_ptr<utils::SystemTimeHandler>&& system_time_handler);
+
+ /**
+ * \brief Destructor
+ */
+ ~SecurityManagerImpl();
+
/**
* \brief Add received from Mobile Application message
* Overriden ProtocolObserver::OnMessageReceived method
@@ -133,7 +145,8 @@ class SecurityManagerImpl : public SecurityManager,
* identifier
* @return new \c SSLContext or \c NULL on any error
*/
- SSLContext* CreateSSLContext(const uint32_t& connection_key) OVERRIDE;
+ SSLContext* CreateSSLContext(const uint32_t& connection_key,
+ ContextCreationStrategy cc_strategy) OVERRIDE;
/**
* \brief Start handshake as SSL client
@@ -141,16 +154,32 @@ class SecurityManagerImpl : public SecurityManager,
void StartHandshake(uint32_t connection_key) OVERRIDE;
/**
+ * @brief PostponeHandshake allows to postpone handshake. It notifies
+ * cryptomanager that certificate should be updated and adds specified
+ * connection key to the list of the certificate awaiting connections.
+ * @param connection_key the identifier for connection to postpone handshake.
+ */
+ void PostponeHandshake(const uint32_t connection_key) OVERRIDE;
+
+ /**
* @brief Checks whether certificate should be updated
* @return true if certificate should be updated otherwise false
*/
- bool IsCertificateUpdateRequired() OVERRIDE;
+ bool IsCertificateUpdateRequired(const uint32_t connection_key) OVERRIDE;
+
+ /**
+ * @brief Checks whether system time ready notification
+ * was received from hmi
+ * @return true if received otherwise false
+ */
+ bool IsSystemTimeProviderReady() const OVERRIDE;
/**
* \brief Add/Remove for SecurityManagerListener
*/
void AddListener(SecurityManagerListener* const listener) OVERRIDE;
void RemoveListener(SecurityManagerListener* const listener) OVERRIDE;
+
/**
* \brief Notifiers for listeners
* \param connection_key Unique key used by other components as session
@@ -217,6 +246,39 @@ class SecurityManagerImpl : public SecurityManager,
*/
void SendQuery(const SecurityQuery& query, const uint32_t connection_key);
+ /**
+ * @brief OnCertificateUpdated allows to obtain notification when certificate
+ * has been updated with policy table update. Pass this certificate to crypto
+ * manager for further processing. Also process postopnes handshake for the
+ * certain connection key.
+ *
+ * @param data the certificates content.
+ * @return always true.
+ */
+ bool OnCertificateUpdated(const std::string& data) OVERRIDE;
+
+ /**
+ * @brief ResumeHandshake allows to resume handshake after certificate has
+ * been updated.
+ * @param connection_key the connection identifier to start handshake.
+ */
+ void ResumeHandshake(uint32_t connection_key);
+
+ /**
+ * @brief ProceedHandshake starts the handshake process.
+ * @param ssl_context ssl context for the handshake. COntains certificate,
+ * keys, etc.
+ * @param connection_key the connection identifier to process handshake.
+ */
+ void ProceedHandshake(SSLContext* ssl_context, uint32_t connection_key);
+
+ /**
+ * @brief OnSystemTimeArrived method which notifies
+ * crypto manager with updated time in order to check certificate validity
+ * @param utc_time the current system time.
+ */
+ void OnSystemTimeArrived(const time_t utc_time) OVERRIDE;
+
// Thread that pumps handshake data
SecurityMessageLoop security_messages_;
@@ -235,7 +297,17 @@ class SecurityManagerImpl : public SecurityManager,
/**
*\brief List of listeners for notify handshake done result
*/
+
std::list<SecurityManagerListener*> listeners_;
+
+ std::unique_ptr<utils::SystemTimeHandler> system_time_handler_;
+ sync_primitives::Lock connections_lock_;
+ std::set<uint32_t> awaiting_certificate_connections_;
+ std::set<uint32_t> awaiting_time_connections_;
+
+ mutable sync_primitives::Lock waiters_lock_;
+ volatile bool waiting_for_certificate_;
+ volatile bool waiting_for_time_;
DISALLOW_COPY_AND_ASSIGN(SecurityManagerImpl);
};
} // namespace security_manager
diff --git a/src/components/security_manager/src/crypto_manager_impl.cc b/src/components/security_manager/src/crypto_manager_impl.cc
index 2cc88c5966..bdf266fda8 100644
--- a/src/components/security_manager/src/crypto_manager_impl.cc
+++ b/src/components/security_manager/src/crypto_manager_impl.cc
@@ -63,7 +63,12 @@ namespace {
int debug_callback(int preverify_ok, X509_STORE_CTX* ctx) {
if (!preverify_ok) {
const int error = X509_STORE_CTX_get_error(ctx);
- UNUSED(error);
+ if (error == X509_V_ERR_CERT_NOT_YET_VALID ||
+ error == X509_V_ERR_CERT_HAS_EXPIRED) {
+ // return success result code instead of error because start
+ // and expiration cert dates will be checked by SDL
+ return 1;
+ }
LOG4CXX_WARN(logger_,
"Certificate verification failed with error "
<< error << " \"" << X509_verify_cert_error_string(error)
@@ -269,24 +274,17 @@ std::string CryptoManagerImpl::LastError() const {
return std::string(reason ? reason : "");
}
-bool CryptoManagerImpl::IsCertificateUpdateRequired() const {
+bool CryptoManagerImpl::IsCertificateUpdateRequired(
+ const time_t system_time, const time_t certificates_time) const {
LOG4CXX_AUTO_TRACE(logger_);
- const time_t cert_date = mktime(&expiration_time_);
+ const double seconds = difftime(certificates_time, system_time);
- if (cert_date == -1) {
- LOG4CXX_WARN(logger_,
- "The certifiacte expiration time cannot be represented.");
- return false;
- }
- const time_t now = time(NULL);
- const double seconds = difftime(cert_date, now);
+ LOG4CXX_DEBUG(
+ logger_, "Certificate UTC time: " << asctime(gmtime(&certificates_time)));
- LOG4CXX_DEBUG(logger_,
- "Certificate expiration time: " << asctime(&expiration_time_));
- LOG4CXX_DEBUG(logger_,
- "Host time: " << asctime(localtime(&now))
- << ". Seconds before expiration: " << seconds);
+ LOG4CXX_DEBUG(logger_, "Host UTC time: " << asctime(gmtime(&system_time)));
+ LOG4CXX_DEBUG(logger_, "Seconds before expiration: " << seconds);
if (seconds < 0) {
LOG4CXX_WARN(logger_, "Certificate is already expired.");
return true;
@@ -336,8 +334,6 @@ bool CryptoManagerImpl::set_certificate(const std::string& cert_data) {
return false;
}
- asn1_time_to_tm(X509_get_notAfter(cert));
-
if (!SSL_CTX_use_PrivateKey(context_, pkey)) {
LOG4CXX_ERROR(logger_, "Could not use key: " << LastError());
return false;
@@ -364,7 +360,8 @@ bool CryptoManagerImpl::set_certificate(const std::string& cert_data) {
return true;
}
-int CryptoManagerImpl::pull_number_from_buf(char* buf, int* idx) {
+int CryptoManagerImpl::SSLContextImpl::get_number_from_char_buf(
+ char* buf, int* idx) const {
if (!idx) {
return 0;
}
@@ -373,40 +370,6 @@ int CryptoManagerImpl::pull_number_from_buf(char* buf, int* idx) {
return val;
}
-void CryptoManagerImpl::asn1_time_to_tm(ASN1_TIME* time) {
- char* buf = (char*)time->data;
- int index = 0;
- const int year = pull_number_from_buf(buf, &index);
- if (V_ASN1_GENERALIZEDTIME == time->type) {
- expiration_time_.tm_year =
- (year * 100 - 1900) + pull_number_from_buf(buf, &index);
- } else {
- expiration_time_.tm_year = year < 50 ? year + 100 : year;
- }
-
- const int mon = pull_number_from_buf(buf, &index);
- const int day = pull_number_from_buf(buf, &index);
- const int hour = pull_number_from_buf(buf, &index);
- const int mn = pull_number_from_buf(buf, &index);
-
- expiration_time_.tm_mon = mon - 1;
- expiration_time_.tm_mday = day;
- expiration_time_.tm_hour = hour;
- expiration_time_.tm_min = mn;
-
- if (buf[index] == 'Z') {
- expiration_time_.tm_sec = 0;
- }
- if ((buf[index] == '+') || (buf[index] == '-')) {
- const int mn = pull_number_from_buf(buf, &index);
- const int mn1 = pull_number_from_buf(buf, &index);
- expiration_time_.tm_sec = (mn * 3600) + (mn1 * 60);
- } else {
- const int sec = pull_number_from_buf(buf, &index);
- expiration_time_.tm_sec = sec;
- }
-}
-
void CryptoManagerImpl::InitCertExpTime() {
strptime("1 Jan 1970 00:00:00", "%d %b %Y %H:%M:%S", &expiration_time_);
}
diff --git a/src/components/security_manager/src/security_manager_impl.cc b/src/components/security_manager/src/security_manager_impl.cc
index 1853b218b4..d68e6b456e 100644
--- a/src/components/security_manager/src/security_manager_impl.cc
+++ b/src/components/security_manager/src/security_manager_impl.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Ford Motor Company
+ * Copyright (c) 2018, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,11 +31,13 @@
*/
#include "security_manager/security_manager_impl.h"
+#include <functional>
#include "security_manager/crypto_manager_impl.h"
#include "protocol_handler/protocol_packet.h"
#include "utils/logger.h"
#include "utils/byte_order.h"
#include "json/json.h"
+#include "utils/helpers.h"
namespace security_manager {
@@ -44,11 +46,22 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "SecurityManager")
static const char* kErrId = "id";
static const char* kErrText = "text";
-SecurityManagerImpl::SecurityManagerImpl()
+SecurityManagerImpl::SecurityManagerImpl(
+ std::unique_ptr<utils::SystemTimeHandler>&& system_time_handler)
: security_messages_("SecurityManager", this)
, session_observer_(NULL)
, crypto_manager_(NULL)
- , protocol_handler_(NULL) {}
+ , protocol_handler_(NULL)
+ , system_time_handler_(std::move(system_time_handler))
+ , waiting_for_certificate_(false)
+ , waiting_for_time_(false) {
+ DCHECK(system_time_handler_);
+ system_time_handler_->SubscribeOnSystemTime(this);
+}
+
+SecurityManagerImpl::~SecurityManagerImpl() {
+ system_time_handler_->UnSubscribeFromSystemTime(this);
+}
void SecurityManagerImpl::OnMessageReceived(
const ::protocol_handler::RawMessagePtr message) {
@@ -136,16 +149,20 @@ void SecurityManagerImpl::Handle(const SecurityMessage message) {
}
security_manager::SSLContext* SecurityManagerImpl::CreateSSLContext(
- const uint32_t& connection_key) {
+ const uint32_t& connection_key, ContextCreationStrategy cc_strategy) {
LOG4CXX_INFO(logger_, "ProtectService processing");
DCHECK(session_observer_);
DCHECK(crypto_manager_);
- security_manager::SSLContext* ssl_context = session_observer_->GetSSLContext(
- connection_key, protocol_handler::kControl);
- // return exists SSLCOntext for current connection/session
- if (ssl_context) {
- return ssl_context;
+ security_manager::SSLContext* ssl_context = NULL;
+ if (kUseExisting == cc_strategy) {
+ security_manager::SSLContext* ssl_context =
+ session_observer_->GetSSLContext(connection_key,
+ protocol_handler::kControl);
+ // If SSLContext for current connection/session exists - return it
+ if (ssl_context) {
+ return ssl_context;
+ }
}
ssl_context = crypto_manager_->CreateSSLContext();
@@ -172,6 +189,40 @@ security_manager::SSLContext* SecurityManagerImpl::CreateSSLContext(
return ssl_context;
}
+void SecurityManagerImpl::PostponeHandshake(const uint32_t connection_key) {
+ LOG4CXX_TRACE(logger_, "Handshake postponed");
+ sync_primitives::AutoLock lock(connections_lock_);
+ if (waiting_for_certificate_) {
+ awaiting_certificate_connections_.insert(connection_key);
+ }
+ if (waiting_for_time_) {
+ awaiting_time_connections_.insert(connection_key);
+ }
+}
+
+void SecurityManagerImpl::ResumeHandshake(uint32_t connection_key) {
+ LOG4CXX_TRACE(logger_, "Handshake resumed");
+
+ security_manager::SSLContext* ssl_context =
+ CreateSSLContext(connection_key, kForceRecreation);
+
+ if (!ssl_context) {
+ LOG4CXX_WARN(logger_,
+ "Unable to resume handshake. No SSL context for key "
+ << connection_key);
+ return;
+ }
+
+ ssl_context->ResetConnection();
+ if (!ssl_context->HasCertificate()) {
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Fail);
+ return;
+ }
+
+ ProceedHandshake(ssl_context, connection_key);
+}
+
void SecurityManagerImpl::StartHandshake(uint32_t connection_key) {
DCHECK(session_observer_);
LOG4CXX_INFO(logger_, "StartHandshake: connection_key " << connection_key);
@@ -187,6 +238,35 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) {
SSLContext::Handshake_Result_Fail);
return;
}
+ if (!ssl_context->HasCertificate()) {
+ LOG4CXX_ERROR(logger_, "Security certificate is absent");
+ sync_primitives::AutoLock lock(waiters_lock_);
+ waiting_for_certificate_ = true;
+ NotifyOnCertififcateUpdateRequired();
+ }
+
+ {
+ sync_primitives::AutoLock lock(waiters_lock_);
+ waiting_for_time_ = true;
+ }
+
+ PostponeHandshake(connection_key);
+ system_time_handler_->QuerySystemTime();
+}
+
+bool SecurityManagerImpl::IsSystemTimeProviderReady() const {
+ return system_time_handler_->system_time_can_be_received();
+}
+
+void SecurityManagerImpl::ProceedHandshake(
+ security_manager::SSLContext* ssl_context, uint32_t connection_key) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!ssl_context) {
+ LOG4CXX_WARN(logger_,
+ "Unable to process handshake. No SSL context for key "
+ << connection_key);
+ return;
+ }
if (ssl_context->IsInitCompleted()) {
NotifyListenersOnHandshakeDone(connection_key,
@@ -194,8 +274,33 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) {
return;
}
- ssl_context->SetHandshakeContext(
- session_observer_->GetHandshakeContext(connection_key));
+ time_t cert_due_date;
+ if (!ssl_context->GetCertificateDueDate(cert_due_date)) {
+ LOG4CXX_ERROR(logger_, "Failed to get certificate due date!");
+ return;
+ }
+
+ if (crypto_manager_->IsCertificateUpdateRequired(
+ system_time_handler_->GetUTCTime(), cert_due_date)) {
+ LOG4CXX_DEBUG(logger_, "Host certificate update required");
+ if (helpers::in_range(awaiting_certificate_connections_, connection_key)) {
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_CertExpired);
+ return;
+ }
+ {
+ sync_primitives::AutoLock lock(waiters_lock_);
+ waiting_for_certificate_ = true;
+ }
+ PostponeHandshake(connection_key);
+ NotifyOnCertififcateUpdateRequired();
+ return;
+ }
+
+ SSLContext::HandshakeContext handshake_context =
+ session_observer_->GetHandshakeContext(connection_key);
+ handshake_context.system_time = system_time_handler_->GetUTCTime();
+ ssl_context->SetHandshakeContext(handshake_context);
size_t data_size = 0;
const uint8_t* data = NULL;
@@ -216,9 +321,21 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) {
}
}
-bool SecurityManagerImpl::IsCertificateUpdateRequired() {
+bool SecurityManagerImpl::IsCertificateUpdateRequired(
+ const uint32_t connection_key) {
LOG4CXX_AUTO_TRACE(logger_);
- return crypto_manager_->IsCertificateUpdateRequired();
+ security_manager::SSLContext* ssl_context =
+ CreateSSLContext(connection_key, kUseExisting);
+ DCHECK_OR_RETURN(ssl_context, true);
+ LOG4CXX_DEBUG(logger_,
+ "Set SSL context to connection_key " << connection_key);
+ time_t cert_due_date;
+ if (!ssl_context->GetCertificateDueDate(cert_due_date)) {
+ LOG4CXX_ERROR(logger_, "Failed to get certificate due date!");
+ return true;
+ }
+ return crypto_manager_->IsCertificateUpdateRequired(
+ system_time_handler_->GetUTCTime(), cert_due_date);
}
void SecurityManagerImpl::AddListener(SecurityManagerListener* const listener) {
@@ -227,7 +344,6 @@ void SecurityManagerImpl::AddListener(SecurityManagerListener* const listener) {
"Invalid (NULL) pointer to SecurityManagerListener.");
return;
}
- LOG4CXX_DEBUG(logger_, "Adding listener " << listener);
listeners_.push_back(listener);
}
@@ -241,6 +357,37 @@ void SecurityManagerImpl::RemoveListener(
listeners_.remove(listener);
}
+bool SecurityManagerImpl::OnCertificateUpdated(const std::string& data) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ {
+ sync_primitives::AutoLock lock(waiters_lock_);
+ waiting_for_certificate_ = false;
+ }
+ crypto_manager_->OnCertificateUpdated(data);
+ std::for_each(
+ awaiting_certificate_connections_.begin(),
+ awaiting_certificate_connections_.end(),
+ std::bind1st(std::mem_fun(&SecurityManagerImpl::ResumeHandshake), this));
+
+ std::set<uint32_t>().swap(awaiting_certificate_connections_);
+ return true;
+}
+
+void SecurityManagerImpl::OnSystemTimeArrived(const time_t utc_time) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ {
+ sync_primitives::AutoLock lock(waiters_lock_);
+ waiting_for_time_ = false;
+ }
+
+ std::for_each(
+ awaiting_time_connections_.begin(),
+ awaiting_time_connections_.end(),
+ std::bind1st(std::mem_fun(&SecurityManagerImpl::ResumeHandshake), this));
+
+ std::set<uint32_t>().swap(awaiting_time_connections_);
+}
+
void SecurityManagerImpl::NotifyListenersOnHandshakeDone(
const uint32_t& connection_key, SSLContext::HandshakeResult error) {
LOG4CXX_AUTO_TRACE(logger_);
diff --git a/src/components/security_manager/src/ssl_context_impl.cc b/src/components/security_manager/src/ssl_context_impl.cc
index 0b30198f4c..bccb885511 100644
--- a/src/components/security_manager/src/ssl_context_impl.cc
+++ b/src/components/security_manager/src/ssl_context_impl.cc
@@ -77,6 +77,7 @@ bool CryptoManagerImpl::SSLContextImpl::IsInitCompleted() const {
SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::StartHandshake(
const uint8_t** const out_data, size_t* out_data_size) {
+ LOG4CXX_AUTO_TRACE(logger_);
is_handshake_pending_ = true;
return DoHandshakeStep(NULL, 0, out_data, out_data_size);
}
@@ -174,6 +175,7 @@ const std::string CryptoManagerImpl::SSLContextImpl::RemoveDisallowedInfo(
void CryptoManagerImpl::SSLContextImpl::PrintCertData(
X509* cert, const std::string& cert_owner) {
+ LOG4CXX_AUTO_TRACE(logger_);
if (!cert) {
LOG4CXX_DEBUG(logger_, "Empty certificate data");
return;
@@ -206,6 +208,7 @@ void CryptoManagerImpl::SSLContextImpl::PrintCertData(
}
void CryptoManagerImpl::SSLContextImpl::PrintCertInfo() {
+ LOG4CXX_AUTO_TRACE(logger_);
PrintCertData(SSL_get_certificate(connection_), "HU's");
STACK_OF(X509)* peer_certs = SSL_get_peer_cert_chain(connection_);
@@ -217,12 +220,42 @@ void CryptoManagerImpl::SSLContextImpl::PrintCertInfo() {
SSLContext::HandshakeResult
CryptoManagerImpl::SSLContextImpl::CheckCertContext() {
+ LOG4CXX_AUTO_TRACE(logger_);
X509* cert = SSL_get_peer_certificate(connection_);
if (!cert) {
// According to the openssl documentation the peer certificate
// might be ommitted for the SERVER but required for the cient.
return CLIENT == mode_ ? Handshake_Result_Fail : Handshake_Result_Success;
}
+ ASN1_TIME* notBefore = X509_get_notBefore(cert);
+ ASN1_TIME* notAfter = X509_get_notAfter(cert);
+
+ time_t start = convert_asn1_time_to_time_t(notBefore);
+ time_t end = convert_asn1_time_to_time_t(notAfter);
+
+ const double start_seconds = difftime(hsh_context_.system_time, start);
+ const double end_seconds = difftime(end, hsh_context_.system_time);
+
+ if (start_seconds < 0) {
+ LOG4CXX_ERROR(logger_,
+ "Certificate is not yet valid. Time before validity "
+ << start_seconds << " seconds");
+ return Handshake_Result_NotYetValid;
+ } else {
+ LOG4CXX_DEBUG(logger_,
+ "Time since certificate validity " << start_seconds
+ << "seconds");
+ }
+
+ if (end_seconds < 0) {
+ LOG4CXX_ERROR(logger_,
+ "Certificate already expired. Time after expiration "
+ << end_seconds << " seconds");
+ return Handshake_Result_CertExpired;
+ } else {
+ LOG4CXX_DEBUG(logger_,
+ "Time until expiration " << end_seconds << "seconds");
+ }
X509_NAME* subj_name = X509_get_subject_name(cert);
@@ -247,6 +280,47 @@ CryptoManagerImpl::SSLContextImpl::CheckCertContext() {
return Handshake_Result_Success;
}
+time_t CryptoManagerImpl::SSLContextImpl::convert_asn1_time_to_time_t(
+ ASN1_TIME* time_to_convert) const {
+ struct tm cert_time;
+ memset(&cert_time, 0, sizeof(struct tm));
+ // the minimum value for day of month is 1, otherwise exception will be thrown
+ cert_time.tm_mday = 1;
+ char* buf = reinterpret_cast<char*>(time_to_convert->data);
+ int index = 0;
+ const int year = get_number_from_char_buf(buf, &index);
+ if (V_ASN1_GENERALIZEDTIME == time_to_convert->type) {
+ cert_time.tm_year =
+ (year * 100 - 1900) + get_number_from_char_buf(buf, &index);
+ } else {
+ cert_time.tm_year = year < 50 ? year + 100 : year;
+ }
+
+ const int mon = get_number_from_char_buf(buf, &index);
+ const int day = get_number_from_char_buf(buf, &index);
+ const int hour = get_number_from_char_buf(buf, &index);
+ const int mn = get_number_from_char_buf(buf, &index);
+
+ cert_time.tm_mon = mon - 1;
+ cert_time.tm_mday = day;
+ cert_time.tm_hour = hour;
+ cert_time.tm_min = mn;
+
+ if (buf[index] == 'Z') {
+ cert_time.tm_sec = 0;
+ }
+ if ((buf[index] == '+') || (buf[index] == '-')) {
+ const int mn = get_number_from_char_buf(buf, &index);
+ const int mn1 = get_number_from_char_buf(buf, &index);
+ cert_time.tm_sec = (mn * 3600) + (mn1 * 60);
+ } else {
+ const int sec = get_number_from_char_buf(buf, &index);
+ cert_time.tm_sec = sec;
+ }
+
+ return mktime(&cert_time);
+}
+
bool CryptoManagerImpl::SSLContextImpl::ReadHandshakeData(
const uint8_t** const out_data, size_t* out_data_size) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -288,7 +362,9 @@ bool CryptoManagerImpl::SSLContextImpl::WriteHandshakeData(
SSLContext::HandshakeResult
CryptoManagerImpl::SSLContextImpl::PerformHandshake() {
+ LOG4CXX_AUTO_TRACE(logger_);
const int handshake_result = SSL_do_handshake(connection_);
+ LOG4CXX_TRACE(logger_, "Handshake result: " << handshake_result);
if (handshake_result == 1) {
const HandshakeResult result = CheckCertContext();
if (result != Handshake_Result_Success) {
@@ -307,6 +383,7 @@ CryptoManagerImpl::SSLContextImpl::PerformHandshake() {
is_handshake_pending_ = false;
} else if (handshake_result == 0) {
+ LOG4CXX_DEBUG(logger_, "SSL handshake failed");
SSL_clear(connection_);
is_handshake_pending_ = false;
return Handshake_Result_Fail;
@@ -447,6 +524,25 @@ bool CryptoManagerImpl::SSLContextImpl::IsHandshakePending() const {
return is_handshake_pending_;
}
+bool CryptoManagerImpl::SSLContextImpl::GetCertificateDueDate(
+ time_t& due_date) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ X509* cert = SSL_get_certificate(connection_);
+ if (!cert) {
+ LOG4CXX_DEBUG(logger_, "Get certificate failed.");
+ return false;
+ }
+
+ due_date = convert_asn1_time_to_time_t(X509_get_notAfter(cert));
+
+ return true;
+}
+
+bool CryptoManagerImpl::SSLContextImpl::HasCertificate() const {
+ return SSL_get_certificate(connection_) != NULL;
+}
+
CryptoManagerImpl::SSLContextImpl::~SSLContextImpl() {
SSL_shutdown(connection_);
SSL_free(connection_);
diff --git a/src/components/security_manager/test/crypto_manager_impl_test.cc b/src/components/security_manager/test/crypto_manager_impl_test.cc
index b30684e5f6..fb645b175d 100644
--- a/src/components/security_manager/test/crypto_manager_impl_test.cc
+++ b/src/components/security_manager/test/crypto_manager_impl_test.cc
@@ -210,7 +210,10 @@ TEST_F(CryptoManagerTest, OnCertificateUpdated) {
}
TEST_F(CryptoManagerTest, OnCertificateUpdated_UpdateNotRequired) {
+ time_t system_time = 0;
+ time_t certificates_time = 1;
size_t updates_before = 0;
+
SetInitialValues(
security_manager::CLIENT, security_manager::TLSv1_2, kAllCiphers);
ASSERT_TRUE(crypto_manager_->Init());
@@ -218,7 +221,8 @@ TEST_F(CryptoManagerTest, OnCertificateUpdated_UpdateNotRequired) {
EXPECT_CALL(*mock_security_manager_settings_, update_before_hours())
.WillOnce(Return(updates_before));
- EXPECT_FALSE(crypto_manager_->IsCertificateUpdateRequired());
+ EXPECT_FALSE(crypto_manager_->IsCertificateUpdateRequired(system_time,
+ certificates_time));
size_t max_updates_ = std::numeric_limits<size_t>::max();
SetInitialValues(
@@ -227,7 +231,8 @@ TEST_F(CryptoManagerTest, OnCertificateUpdated_UpdateNotRequired) {
.WillOnce(Return(max_updates_));
ASSERT_TRUE(crypto_manager_->Init());
- EXPECT_TRUE(crypto_manager_->IsCertificateUpdateRequired());
+ EXPECT_TRUE(crypto_manager_->IsCertificateUpdateRequired(system_time,
+ certificates_time));
}
TEST_F(CryptoManagerTest, OnCertificateUpdated_NotInitialized) {
diff --git a/src/components/security_manager/test/security_manager_test.cc b/src/components/security_manager/test/security_manager_test.cc
index b334e78e19..4fe66498ea 100644
--- a/src/components/security_manager/test/security_manager_test.cc
+++ b/src/components/security_manager/test/security_manager_test.cc
@@ -44,6 +44,7 @@
#include "security_manager/mock_ssl_context.h"
#include "security_manager/mock_crypto_manager.h"
#include "security_manager/mock_security_manager_listener.h"
+#include "utils/mock_system_time_handler.h"
#include "utils/make_shared.h"
#include "utils/test_async_waiter.h"
@@ -95,8 +96,12 @@ const uint32_t kAsyncExpectationsTimeout = 10000u;
class SecurityManagerTest : public ::testing::Test {
protected:
+ SecurityManagerTest()
+ : mock_system_time_handler(
+ std::unique_ptr<MockSystemTimeHandler>(new MockSystemTimeHandler()))
+ , security_manager_(
+ new SecurityManagerImpl(std::move(mock_system_time_handler))) {}
void SetUp() OVERRIDE {
- security_manager_.reset(new SecurityManagerImpl());
security_manager_->set_session_observer(&mock_session_observer);
security_manager_->set_protocol_handler(&mock_protocol_handler);
mock_sm_listener.reset(new testing::StrictMock<
@@ -105,7 +110,7 @@ class SecurityManagerTest : public ::testing::Test {
}
void SetMockCryptoManager() {
- EXPECT_CALL(mock_crypto_manager, IsCertificateUpdateRequired())
+ EXPECT_CALL(mock_crypto_manager, IsCertificateUpdateRequired(_, _))
.WillRepeatedly(Return(false));
security_manager_->set_crypto_manager(&mock_crypto_manager);
}
@@ -152,8 +157,9 @@ class SecurityManagerTest : public ::testing::Test {
EmulateMobileMessage(header, data, data_size);
}
}
- ::utils::SharedPtr<SecurityManagerImpl> security_manager_;
+
// Strict mocks (same as all methods EXPECT_CALL().Times(0))
+
testing::StrictMock<protocol_handler_test::MockSessionObserver>
mock_session_observer;
testing::StrictMock<protocol_handler_test::MockProtocolHandler>
@@ -166,6 +172,8 @@ class SecurityManagerTest : public ::testing::Test {
mock_ssl_context_exists;
std::unique_ptr<testing::StrictMock<
security_manager_test::MockSecurityManagerListener> > mock_sm_listener;
+ std::unique_ptr<MockSystemTimeHandler> mock_system_time_handler;
+ std::shared_ptr<SecurityManagerImpl> security_manager_;
};
// Test Bodies
@@ -174,7 +182,6 @@ class SecurityManagerTest : public ::testing::Test {
* and shall not call any methodes
*/
TEST_F(SecurityManagerTest, SetNULL_Intefaces) {
- security_manager_.reset(new SecurityManagerImpl());
security_manager_->set_session_observer(NULL);
security_manager_->set_protocol_handler(NULL);
security_manager_->set_crypto_manager(NULL);
@@ -398,7 +405,9 @@ TEST_F(SecurityManagerTest, CreateSSLContext_ServiceAlreadyProtected) {
EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl))
.WillOnce(Return(&mock_ssl_context_new));
- const SSLContext* result = security_manager_->CreateSSLContext(key);
+ const SSLContext* result = security_manager_->CreateSSLContext(
+ key,
+ security_manager::SecurityManager::ContextCreationStrategy::kUseExisting);
EXPECT_EQ(&mock_ssl_context_new, result);
}
/*
@@ -424,7 +433,9 @@ TEST_F(SecurityManagerTest, CreateSSLContext_ErrorCreateSSL) {
.WillOnce(ReturnNull());
EXPECT_CALL(mock_crypto_manager, CreateSSLContext()).WillOnce(ReturnNull());
- const SSLContext* result = security_manager_->CreateSSLContext(key);
+ const SSLContext* result = security_manager_->CreateSSLContext(
+ key,
+ security_manager::SecurityManager::ContextCreationStrategy::kUseExisting);
EXPECT_EQ(NULL, result);
}
/*
@@ -457,7 +468,9 @@ TEST_F(SecurityManagerTest, CreateSSLContext_SetSSLContextError) {
EXPECT_CALL(mock_session_observer, SetSSLContext(key, &mock_ssl_context_new))
.WillOnce(Return(SecurityManager::ERROR_UNKNOWN_INTERNAL_ERROR));
- const SSLContext* result = security_manager_->CreateSSLContext(key);
+ const SSLContext* result = security_manager_->CreateSSLContext(
+ key,
+ security_manager::SecurityManager::ContextCreationStrategy::kUseExisting);
EXPECT_EQ(NULL, result);
}
/*
@@ -470,7 +483,6 @@ TEST_F(SecurityManagerTest, CreateSSLContext_Success) {
// Emulate SessionObserver and CryptoManager result
EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl))
- .WillOnce(ReturnNull())
.
// additional check for debug code
WillOnce(Return(&mock_ssl_context_exists));
@@ -479,7 +491,10 @@ TEST_F(SecurityManagerTest, CreateSSLContext_Success) {
EXPECT_CALL(mock_session_observer, SetSSLContext(key, &mock_ssl_context_new))
.WillOnce(Return(SecurityManager::ERROR_SUCCESS));
- const SSLContext* result = security_manager_->CreateSSLContext(key);
+ const SSLContext* result = security_manager_->CreateSSLContext(
+ key,
+ security_manager::SecurityManager::ContextCreationStrategy::
+ kForceRecreation);
EXPECT_EQ(&mock_ssl_context_new, result);
}
/*
@@ -521,109 +536,27 @@ TEST_F(SecurityManagerTest, StartHandshake_SSLInternalError) {
uint32_t connection_id = 0;
uint8_t session_id = 0;
- // uint8_t protocol_version = 0;
+
EXPECT_CALL(mock_session_observer, PairFromKey(key, _, _));
- EXPECT_CALL(mock_session_observer, GetHandshakeContext(key))
- .WillOnce(Return(SSLContext::HandshakeContext()));
EXPECT_CALL(mock_session_observer,
ProtocolVersionUsed(connection_id, session_id, _))
.WillOnce(Return(true));
-
- // Expect InternalError with ERROR_ID
- EXPECT_CALL(
- mock_protocol_handler,
- SendMessageToMobileApp(
- InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), is_final));
// Expect notifying listeners (unsuccess)
EXPECT_CALL(*mock_sm_listener,
OnHandshakeDone(key, SSLContext::Handshake_Result_Fail))
.WillOnce(Return(true));
-
- // Emulate SessionObserver result
EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl))
- .WillOnce(Return(&mock_ssl_context_exists));
- EXPECT_CALL(mock_ssl_context_exists, IsInitCompleted())
- .WillOnce(Return(false));
- EXPECT_CALL(mock_ssl_context_exists, SetHandshakeContext(_));
- EXPECT_CALL(mock_ssl_context_exists, StartHandshake(_, _))
- .WillOnce(DoAll(SetArgPointee<0>(handshake_data_out_pointer),
- SetArgPointee<1>(handshake_data_out_size),
- Return(SSLContext::Handshake_Result_Fail)));
+ .WillOnce(ReturnNull());
+ // Expect InternalError with ERROR_ID
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp(
+ InternalErrorWithErrId(SecurityManager::ERROR_INTERNAL), is_final));
security_manager_->StartHandshake(key);
-
- // Listener was destroyed after OnHandshakeDone call
mock_sm_listener.release();
}
-/*
- * Shall send data on call StartHandshake
- */
-TEST_F(SecurityManagerTest, StartHandshake_SSLInitIsNotComplete) {
- SetMockCryptoManager();
- uint32_t connection_id = 0;
- uint8_t session_id = 0;
- // uint8_t protocol_version = 0;
- EXPECT_CALL(mock_session_observer, PairFromKey(key, _, _));
- EXPECT_CALL(mock_session_observer, GetHandshakeContext(key))
- .Times(3)
- .WillRepeatedly(Return(SSLContext::HandshakeContext()));
- EXPECT_CALL(mock_session_observer,
- ProtocolVersionUsed(connection_id, session_id, _))
- .WillOnce(Return(true));
- // Expect send one message (with correct pointer and size data)
- EXPECT_CALL(mock_protocol_handler, SendMessageToMobileApp(_, is_final));
-
- // Return mock SSLContext
- EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl))
- .Times(3)
- .WillRepeatedly(Return(&mock_ssl_context_exists));
- // Expect initialization check on each call StartHandshake
- EXPECT_CALL(mock_ssl_context_exists, IsInitCompleted())
- .Times(3)
- .WillRepeatedly(Return(false));
- EXPECT_CALL(mock_ssl_context_exists, SetHandshakeContext(_)).Times(3);
-
- // Emulate SSLContext::StartHandshake with different parameters
- // Only on both correct - data and size shall be send message to mobile app
- EXPECT_CALL(mock_ssl_context_exists, StartHandshake(_, _))
- .WillOnce(DoAll(SetArgPointee<0>(handshake_data_out_pointer),
- SetArgPointee<1>(0),
- Return(SSLContext::Handshake_Result_Success)))
- .WillOnce(DoAll(SetArgPointee<0>((uint8_t*)NULL),
- SetArgPointee<1>(handshake_data_out_size),
- Return(SSLContext::Handshake_Result_Success)))
- .WillOnce(DoAll(SetArgPointee<0>(handshake_data_out_pointer),
- SetArgPointee<1>(handshake_data_out_size),
- Return(SSLContext::Handshake_Result_Success)));
-
- security_manager_->StartHandshake(key);
- security_manager_->StartHandshake(key);
- security_manager_->StartHandshake(key);
-}
-/*
- * Shall notify listeners on call StartHandshake after SSLContext initialization
- * complete
- */
-TEST_F(SecurityManagerTest, StartHandshake_SSLInitIsComplete) {
- SetMockCryptoManager();
- // Expect no message send
- // Expect notifying listeners (success)
- EXPECT_CALL(*mock_sm_listener,
- OnHandshakeDone(key, SSLContext::Handshake_Result_Success))
- .WillOnce(Return(true));
-
- // Emulate SessionObserver result
- EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl))
- .WillOnce(Return(&mock_ssl_context_exists));
- EXPECT_CALL(mock_ssl_context_exists, IsInitCompleted())
- .WillOnce(Return(true));
-
- security_manager_->StartHandshake(key);
-
- // Listener was destroyed after OnHandshakeDone call
- mock_sm_listener.release();
-}
/*
* Shall send InternallError on
* getting SEND_HANDSHAKE_DATA with NULL data
diff --git a/src/components/security_manager/test/ssl_certificate_handshake_test.cc b/src/components/security_manager/test/ssl_certificate_handshake_test.cc
index dc335c8da2..f6521c253a 100644
--- a/src/components/security_manager/test/ssl_certificate_handshake_test.cc
+++ b/src/components/security_manager/test/ssl_certificate_handshake_test.cc
@@ -335,6 +335,9 @@ class SSLHandshakeTest : public testing::Test {
std::string client_certificate_;
std::string client_ciphers_list_;
std::string client_ca_certificate_path_;
+
+ std::vector<int> forced_protected_services_;
+ std::vector<int> forced_unprotected_services_;
};
TEST_F(SSLHandshakeTest, NoVerification) {
diff --git a/src/components/utils/CMakeLists.txt b/src/components/utils/CMakeLists.txt
index 51835c125a..b256a2fadc 100644
--- a/src/components/utils/CMakeLists.txt
+++ b/src/components/utils/CMakeLists.txt
@@ -38,6 +38,7 @@ include_directories (
${COMPONENTS_DIR}/config_profile/include
${COMPONENTS_DIR}/media_manager/include
${COMPONENTS_DIR}/protocol_handler/include
+ ${JSONCPP_INCLUDE_DIRECTORY}
${LOG4CXX_INCLUDE_DIRECTORY}
)
diff --git a/src/components/utils/include/utils/system_time_handler.h b/src/components/utils/include/utils/system_time_handler.h
new file mode 100644
index 0000000000..99bbfa39e5
--- /dev/null
+++ b/src/components/utils/include/utils/system_time_handler.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_
+#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_
+
+#include <time.h>
+
+namespace utils {
+
+/**
+ * @brief The SystemTimeListener interface.
+ * This interface allows to get notifications whenever
+ * system time appears or fails to appear.
+ */
+class SystemTimeListener {
+ public:
+ /**
+ * @brief OnSystemTimeArrived Notify about system time
+ * in utc format
+ * @param utc_time current system time.
+ */
+ virtual void OnSystemTimeArrived(const time_t utc_time) = 0;
+};
+
+/**
+ * @brief SystemTimeHandler the interface which provides the necessary
+ * public API to work with system time. The class does not implement
+ * any logic it's public api forwards call to the private virtual
+ * methods which are suppose to be defined within specific implementation.
+ */
+class SystemTimeHandler {
+ public:
+ /**
+ * @brief SystemTimeHandler creates an instance
+ * for this class.
+ */
+ SystemTimeHandler();
+
+ /**
+ * @brief QuerySystemTime provides the public interface
+ * to retrieve the system time. Interface uses private implementation
+ * hence the logic will be defined within descendant class.
+ */
+ void QuerySystemTime();
+
+ /**
+ * @brief SubscribeOnSystemTime allows to subscribe listener
+ * to the certain event. This class does not provide such storage.
+ * It rather uses private pure virtual function. So the final behaviour
+ * should be defined within the descendant class
+ */
+ void SubscribeOnSystemTime(SystemTimeListener* listener);
+
+ /**
+ * @brief UnSubscribeFromSystemTime allows to unsubscribe listener
+ * from the certain event. This class does not manipulate with storage.
+ * It rather uses private pure virtual function. So the final behaviour
+ * should be defined within the descendant class
+ */
+ void UnSubscribeFromSystemTime(SystemTimeListener* listener);
+
+ /**
+ * @brief GetUTCTime allows to obtain cached result for the
+ * GetSystemTime request
+ * @return utc time.
+ */
+ time_t GetUTCTime();
+
+ /**
+ * @brief Checks if system time is ready
+ * and can be requested by GetSystemTime request
+ * @return True if HMI is ready to provide UTC time
+ * otherwise False
+ */
+ bool system_time_can_be_received() const;
+
+ /**
+ * @brief ~SystemTimeHandler destroys the object
+ */
+ virtual ~SystemTimeHandler();
+
+ private:
+ /**
+ * @brief DoSystemTimeQuery responsible for the system time querying.
+ * It is up to implementator how exactly system is going to receive this time.
+ */
+ virtual void DoSystemTimeQuery() = 0;
+
+ /**
+ * @brief DoSubscribe implements the logic which allows to handle
+ * subscription process. The handling logic should be defined within
+ * descendant class.
+ */
+ virtual void DoSubscribe(SystemTimeListener* listener) = 0;
+
+ /**
+ * @brief DoUnsubscribe implements the logic which allows to handle
+ * unsubscription process. The handling logic should be defined within
+ * descendant class.
+ */
+ virtual void DoUnsubscribe(SystemTimeListener* listener) = 0;
+
+ /**
+ * @brief FetchSystemTime allows to obtain the cached result
+ * for the GetSystemTime request.
+ * @return utc time.
+ */
+ virtual time_t FetchSystemTime() = 0;
+
+ /**
+ * @brief Checks if UTC time is ready to provided by HMI
+ * and can be requested by GetSystemTime request
+ * @return True if HMI is ready to provide UTC time
+ * otherwise False
+ */
+ virtual bool utc_time_can_be_received() const = 0;
+};
+
+} // namespace utils
+
+#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_
diff --git a/src/components/utils/src/system_time_handler.cc b/src/components/utils/src/system_time_handler.cc
new file mode 100644
index 0000000000..ea04d1c0b9
--- /dev/null
+++ b/src/components/utils/src/system_time_handler.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "utils/system_time_handler.h"
+//#include <algorithm>
+
+namespace utils {
+
+SystemTimeHandler::SystemTimeHandler() {}
+
+SystemTimeHandler::~SystemTimeHandler() {}
+
+void SystemTimeHandler::QuerySystemTime() {
+ DoSystemTimeQuery();
+}
+
+void SystemTimeHandler::SubscribeOnSystemTime(SystemTimeListener* listener) {
+ DoSubscribe(listener);
+}
+
+void SystemTimeHandler::UnSubscribeFromSystemTime(
+ SystemTimeListener* listener) {
+ DoUnsubscribe(listener);
+}
+
+time_t SystemTimeHandler::GetUTCTime() {
+ return FetchSystemTime();
+}
+
+bool SystemTimeHandler::system_time_can_be_received() const {
+ return utc_time_can_be_received();
+}
+
+} // namespace utils