summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h19
-rw-r--r--src/components/application_manager/include/application_manager/usage_statistics.h2
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc35
-rw-r--r--src/components/application_manager/src/usage_statistics.cc7
-rw-r--r--src/components/connection_handler/include/connection_handler/connection_handler_impl.h3
-rw-r--r--src/components/connection_handler/include/connection_handler/connection_handler_observer.h8
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc5
-rw-r--r--src/components/include/protocol_handler/session_observer.h3
-rw-r--r--src/components/include/security_manager/security_manager_listener.h2
-rw-r--r--src/components/include/security_manager/ssl_context.h21
-rw-r--r--src/components/policy/src/policy/policy_table/table_struct/types.cc149
-rw-r--r--src/components/policy/src/policy/policy_table/table_struct/types.h18
-rw-r--r--src/components/policy/src/policy/src/cache_manager.cc42
-rw-r--r--src/components/policy/src/policy/src/sql_pt_queries.cc1
-rw-r--r--src/components/policy/src/policy/usage_statistics/include/usage_statistics/statistics_manager.h3
-rw-r--r--src/components/protocol_handler/src/protocol_handler_impl.cc16
-rw-r--r--src/components/security_manager/include/security_manager/crypto_manager_impl.h30
-rw-r--r--src/components/security_manager/include/security_manager/security_manager_impl.h2
-rw-r--r--src/components/security_manager/src/security_manager_impl.cc33
-rw-r--r--src/components/security_manager/src/ssl_context_impl.cc148
20 files changed, 498 insertions, 49 deletions
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 e14d6d4cad..759691ae38 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
@@ -66,6 +66,12 @@
#include "interfaces/v4_protocol_v1_2_no_extra.h"
#include "interfaces/v4_protocol_v1_2_no_extra_schema.h"
+
+#ifdef ENABLE_SECURITY
+#include "security_manager/security_manager_listener.h"
+#include "security_manager/ssl_context.h"
+#endif // ENABLE_SECURITY
+
#ifdef TIME_TESTER
#include "time_metric_observer.h"
#endif // TIME_TESTER
@@ -179,12 +185,14 @@ typedef threads::MessageLoopThread<RawAudioDataQueue> AudioPassThruQueue;
}
typedef std::vector<std::string> RPCParams;
-
class ApplicationManagerImpl : public ApplicationManager,
public hmi_message_handler::HMIMessageObserver,
public protocol_handler::ProtocolObserver,
public connection_handler::ConnectionHandlerObserver,
public policy::PolicyHandlerObserver,
+#ifdef ENABLE_SECURITY
+ public security_manager::SecurityManagerListener,
+#endif // ENABLE_SECURITY
public impl::FromMobileQueue::Handler, public impl::ToMobileQueue::Handler,
public impl::FromHmiQueue::Handler, public impl::ToHmiQueue::Handler,
public impl::AudioPassThruQueue::Handler,
@@ -637,6 +645,15 @@ class ApplicationManagerImpl : public ApplicationManager,
const protocol_handler::ServiceType& type,
const connection_handler::CloseSessionReason& close_reason) OVERRIDE;
+#ifdef ENABLE_SECURITY
+ //Overriden SecurityManagerListener method
+ bool OnHandshakeDone(
+ uint32_t connection_key,
+ security_manager::SSLContext::HandshakeResult result) OVERRIDE FINAL;
+
+ security_manager::SSLContext::HandshakeContext
+ GetHandshakeContext(uint32_t key) const OVERRIDE FINAL;
+#endif // ENABLE_SECURITY
/**
* @ Add notification to collection
*
diff --git a/src/components/application_manager/include/application_manager/usage_statistics.h b/src/components/application_manager/include/application_manager/usage_statistics.h
index d6ff1f2c49..9be1bde7ca 100644
--- a/src/components/application_manager/include/application_manager/usage_statistics.h
+++ b/src/components/application_manager/include/application_manager/usage_statistics.h
@@ -54,6 +54,7 @@ class UsageStatistics {
void RecordAppUserSelection();
void RecordRunAttemptsWhileRevoked();
void RecordRemovalsForBadBehavior();
+ void RecordTLSError();
private:
usage_statistics::AppStopwatch time_in_hmi_state_;
@@ -64,6 +65,7 @@ class UsageStatistics {
usage_statistics::AppCounter count_of_user_selections_;
usage_statistics::AppCounter count_of_run_attempts_while_revoked_;
usage_statistics::AppCounter count_of_removals_for_bad_behavior_;
+ usage_statistics::AppCounter count_of_tls_error_;
};
} // namespace application_manager
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index c5e91acbce..a9e67a93ca 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -1176,8 +1176,43 @@ void ApplicationManagerImpl::OnServiceEndedCallback(
if (Compare<ServiceType, EQ, ONE>(type,
ServiceType::kMobileNav, ServiceType::kAudio)) {
StopNaviService(session_key, type);
+ }
+}
+
+#ifdef ENABLE_SECURITY
+bool ApplicationManagerImpl::OnHandshakeDone(
+ uint32_t connection_key,
+ security_manager::SSLContext::HandshakeResult result) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ using security_manager::SSLContext;
+ using namespace helpers;
+
+ ApplicationSharedPtr app = application(connection_key);
+ DCHECK_OR_RETURN(app, false);
+ if (Compare<SSLContext::HandshakeResult, EQ, ONE> (
+ result,
+ SSLContext::Handshake_Result_CertExpired,
+ SSLContext::Handshake_Result_CertNotSigned,
+ SSLContext::Handshake_Result_AppIDMismatch,
+ SSLContext::Handshake_Result_AppNameMismatch,
+ SSLContext::Handshake_Result_NotYetValid)) {
+ app->usage_report().RecordTLSError();
}
+ return true;
+}
+
+security_manager::SSLContext::HandshakeContext
+ApplicationManagerImpl::GetHandshakeContext(uint32_t key) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ApplicationConstSharedPtr app = application(key);
+ security_manager::SSLContext::HandshakeContext res;
+ res.expected_cn = app->mobile_app_id();
+ res.expected_sn = app->name();
+
+ return res;
}
+#endif // ENABLE_SECURITY
void ApplicationManagerImpl::set_hmi_message_handler(
hmi_message_handler::HMIMessageHandler* handler) {
diff --git a/src/components/application_manager/src/usage_statistics.cc b/src/components/application_manager/src/usage_statistics.cc
index ad986d2223..c3758fa9e2 100644
--- a/src/components/application_manager/src/usage_statistics.cc
+++ b/src/components/application_manager/src/usage_statistics.cc
@@ -66,7 +66,8 @@ UsageStatistics::UsageStatistics(const std::string& app_id,
count_of_run_attempts_while_revoked_(statistics_manager, app_id,
RUN_ATTEMPTS_WHILE_REVOKED),
count_of_removals_for_bad_behavior_(statistics_manager, app_id,
- REMOVALS_MISBEHAVED) {
+ REMOVALS_MISBEHAVED),
+ count_of_tls_error_(statistics_manager, app_id, COUNT_OF_TLS_ERRORS) {
time_in_hmi_state_.Start(SECONDS_HMI_NONE);
}
@@ -122,4 +123,8 @@ void UsageStatistics::RecordRemovalsForBadBehavior() {
++count_of_removals_for_bad_behavior_;
}
+void UsageStatistics::RecordTLSError() {
+ ++count_of_tls_error_;
+}
+
} // namespace application_manager
diff --git a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
index 63568a5927..b861e4f030 100644
--- a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
+++ b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
@@ -289,6 +289,9 @@ class ConnectionHandlerImpl : public ConnectionHandler,
void SetProtectionFlag(
const uint32_t &key,
const protocol_handler::ServiceType &service_type) OVERRIDE;
+
+ security_manager::SSLContext::HandshakeContext
+ GetHandshakeContext(uint32_t key) const OVERRIDE;
#endif // ENABLE_SECURITY
/**
diff --git a/src/components/connection_handler/include/connection_handler/connection_handler_observer.h b/src/components/connection_handler/include/connection_handler/connection_handler_observer.h
index 556a2dc4e2..be7e600556 100644
--- a/src/components/connection_handler/include/connection_handler/connection_handler_observer.h
+++ b/src/components/connection_handler/include/connection_handler/connection_handler_observer.h
@@ -38,6 +38,10 @@
#include "connection_handler/connection_handler.h"
#include "protocol/service_type.h"
+#ifdef ENABLE_SECURITY
+#include "security_manager/ssl_context.h"
+#endif // ENABLE_SECURITY
+
/**
* \namespace connection_handler
* \brief SmartDeviceLink connection_handler namespace.
@@ -100,6 +104,10 @@ class ConnectionHandlerObserver {
const protocol_handler::ServiceType& type,
const connection_handler::CloseSessionReason& close_reason) = 0;
+#ifdef ENABLE_SECURITY
+ virtual security_manager::SSLContext::HandshakeContext
+ GetHandshakeContext(uint32_t key) const = 0;
+#endif // ENABLE_SECURITY
protected:
/**
* \brief Destructor
diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc
index 1fbe26a8f7..7542f311d1 100644
--- a/src/components/connection_handler/src/connection_handler_impl.cc
+++ b/src/components/connection_handler/src/connection_handler_impl.cc
@@ -654,6 +654,11 @@ void ConnectionHandlerImpl::SetProtectionFlag(
Connection &connection = *it->second;
connection.SetProtectionFlag(session_id, service_type);
}
+
+security_manager::SSLContext::HandshakeContext
+ConnectionHandlerImpl::GetHandshakeContext(uint32_t key) const {
+ return connection_handler_observer_->GetHandshakeContext(key);
+}
#endif // ENABLE_SECURITY
void ConnectionHandlerImpl::StartDevicesDiscovery() {
diff --git a/src/components/include/protocol_handler/session_observer.h b/src/components/include/protocol_handler/session_observer.h
index 355c62e646..ed341b3926 100644
--- a/src/components/include/protocol_handler/session_observer.h
+++ b/src/components/include/protocol_handler/session_observer.h
@@ -212,6 +212,9 @@ class SessionObserver {
virtual void SetProtectionFlag(
const uint32_t &key,
const protocol_handler::ServiceType &service_type) = 0;
+
+ virtual security_manager::SSLContext::HandshakeContext
+ GetHandshakeContext(uint32_t key) const = 0;
#endif // ENABLE_SECURITY
protected:
diff --git a/src/components/include/security_manager/security_manager_listener.h b/src/components/include/security_manager/security_manager_listener.h
index 14a5dc3281..1655d15e7e 100644
--- a/src/components/include/security_manager/security_manager_listener.h
+++ b/src/components/include/security_manager/security_manager_listener.h
@@ -42,7 +42,7 @@ class SecurityManagerListener {
* \return \c true on success notification or \c false otherwise
*/
virtual bool OnHandshakeDone(uint32_t connection_key,
- bool success) = 0;
+ SSLContext::HandshakeResult result) = 0;
virtual ~SecurityManagerListener() {}
};
} // namespace security_manager
diff --git a/src/components/include/security_manager/ssl_context.h b/src/components/include/security_manager/ssl_context.h
index e3f1dadc4f..cd82b67461 100644
--- a/src/components/include/security_manager/ssl_context.h
+++ b/src/components/include/security_manager/ssl_context.h
@@ -61,10 +61,21 @@ namespace security_manager {
class SSLContext {
public:
enum HandshakeResult {
- Handshake_Result_Success = 0x0,
- Handshake_Result_Fail = 0x1,
- Handshake_Result_AbnormalFail = 0x2
+ Handshake_Result_Success,
+ Handshake_Result_Fail,
+ Handshake_Result_AbnormalFail,
+ Handshake_Result_CertExpired,
+ Handshake_Result_NotYetValid,
+ Handshake_Result_CertNotSigned,
+ Handshake_Result_AppIDMismatch,
+ Handshake_Result_AppNameMismatch,
};
+
+ struct HandshakeContext {
+ std::string expected_sn;
+ std::string expected_cn;
+ };
+
virtual HandshakeResult StartHandshake(const uint8_t** const out_data,
size_t *out_data_size) = 0;
virtual HandshakeResult DoHandshakeStep(const uint8_t *const in_data,
@@ -79,7 +90,11 @@ class SSLContext {
virtual bool IsHandshakePending() const = 0;
virtual size_t get_max_block_size(size_t mtu) const = 0;
virtual std::string LastError() const = 0;
+
+ virtual void ResetConnection() = 0;
+ virtual void SetHandshakeContext(const HandshakeContext& hsh_ctx) = 0;
virtual ~SSLContext() { }
+
};
} // namespace security_manager
#endif // SRC_COMPONENTS_INCLUDE_SECURITY_MANAGER_SSL_CONTEXT_H_
diff --git a/src/components/policy/src/policy/policy_table/table_struct/types.cc b/src/components/policy/src/policy/policy_table/table_struct/types.cc
index a26c1339ca..f6135921b4 100644
--- a/src/components/policy/src/policy/policy_table/table_struct/types.cc
+++ b/src/components/policy/src/policy/policy_table/table_struct/types.cc
@@ -933,18 +933,109 @@ void ModuleMeta::ReportErrors(rpc::ValidationReport* report__) const {
AppLevel::AppLevel()
: CompositeType(kUninitialized) {
}
+
+AppLevel::AppLevel(uint16_t minutes_in_hmi_full, const std::string& app_registration_language_gui, const std::string& app_registration_language_vui, uint16_t minutes_in_hmi_limited, uint16_t minutes_in_hmi_background, uint16_t minutes_in_hmi_none, uint16_t count_of_user_selections, uint16_t count_of_rejections_sync_out_of_memory, uint16_t count_of_rejections_nickname_mismatch, uint16_t count_of_rejections_duplicate_name, uint16_t count_of_rejected_rpc_calls, uint16_t count_of_rpcs_sent_in_hmi_none, uint16_t count_of_removals_for_bad_behavior, uint16_t count_of_tls_error, uint16_t count_of_run_attempts_while_revoked)
+ : CompositeType(kUninitialized),
+ minutes_in_hmi_full(minutes_in_hmi_full),
+ app_registration_language_gui(app_registration_language_gui),
+ app_registration_language_vui(app_registration_language_vui),
+ minutes_in_hmi_limited(minutes_in_hmi_limited),
+ minutes_in_hmi_background(minutes_in_hmi_background),
+ minutes_in_hmi_none(minutes_in_hmi_none),
+ count_of_user_selections(count_of_user_selections),
+ count_of_rejections_sync_out_of_memory(count_of_rejections_sync_out_of_memory),
+ count_of_rejections_nickname_mismatch(count_of_rejections_nickname_mismatch),
+ count_of_rejections_duplicate_name(count_of_rejections_duplicate_name),
+ count_of_rejected_rpc_calls(count_of_rejected_rpc_calls),
+ count_of_rpcs_sent_in_hmi_none(count_of_rpcs_sent_in_hmi_none),
+ count_of_removals_for_bad_behavior(count_of_removals_for_bad_behavior),
+ count_of_tls_error(count_of_tls_error),
+ count_of_run_attempts_while_revoked(count_of_run_attempts_while_revoked) {
+}
AppLevel::~AppLevel() {
}
AppLevel::AppLevel(const Json::Value* value__)
- : CompositeType(InitHelper(value__, &Json::Value::isObject)) {
+ : CompositeType(InitHelper(value__, &Json::Value::isObject)),
+ minutes_in_hmi_full(impl::ValueMember(value__, "minutes_in_hmi_full")),
+ app_registration_language_gui(impl::ValueMember(value__, "app_registration_language_gui")),
+ app_registration_language_vui(impl::ValueMember(value__, "app_registration_language_vui")),
+ minutes_in_hmi_limited(impl::ValueMember(value__, "minutes_in_hmi_limited")),
+ minutes_in_hmi_background(impl::ValueMember(value__, "minutes_in_hmi_background")),
+ minutes_in_hmi_none(impl::ValueMember(value__, "minutes_in_hmi_none")),
+ count_of_user_selections(impl::ValueMember(value__, "count_of_user_selections")),
+ count_of_rejections_sync_out_of_memory(impl::ValueMember(value__, "count_of_rejections_sync_out_of_memory")),
+ count_of_rejections_nickname_mismatch(impl::ValueMember(value__, "count_of_rejections_nickname_mismatch")),
+ count_of_rejections_duplicate_name(impl::ValueMember(value__, "count_of_rejections_duplicate_name")),
+ count_of_rejected_rpc_calls(impl::ValueMember(value__, "count_of_rejected_rpc_calls")),
+ count_of_rpcs_sent_in_hmi_none(impl::ValueMember(value__, "count_of_rpcs_sent_in_hmi_none")),
+ count_of_removals_for_bad_behavior(impl::ValueMember(value__, "count_of_removals_for_bad_behavior")),
+ count_of_tls_error(impl::ValueMember(value__, "count_of_tls_error")),
+ count_of_run_attempts_while_revoked(impl::ValueMember(value__, "count_of_run_attempts_while_revoked")) {
}
Json::Value AppLevel::ToJsonValue() const {
Json::Value result__(Json::objectValue);
+ impl::WriteJsonField("minutes_in_hmi_full", minutes_in_hmi_full, &result__);
+ impl::WriteJsonField("app_registration_language_gui", app_registration_language_gui, &result__);
+ impl::WriteJsonField("app_registration_language_vui", app_registration_language_vui, &result__);
+ impl::WriteJsonField("minutes_in_hmi_limited", minutes_in_hmi_limited, &result__);
+ impl::WriteJsonField("minutes_in_hmi_background", minutes_in_hmi_background, &result__);
+ impl::WriteJsonField("minutes_in_hmi_none", minutes_in_hmi_none, &result__);
+ impl::WriteJsonField("count_of_user_selections", count_of_user_selections, &result__);
+ impl::WriteJsonField("count_of_rejections_sync_out_of_memory", count_of_rejections_sync_out_of_memory, &result__);
+ impl::WriteJsonField("count_of_rejections_nickname_mismatch", count_of_rejections_nickname_mismatch, &result__);
+ impl::WriteJsonField("count_of_rejections_duplicate_name", count_of_rejections_duplicate_name, &result__);
+ impl::WriteJsonField("count_of_rejected_rpc_calls", count_of_rejected_rpc_calls, &result__);
+ impl::WriteJsonField("count_of_rpcs_sent_in_hmi_none", count_of_rpcs_sent_in_hmi_none, &result__);
+ impl::WriteJsonField("count_of_removals_for_bad_behavior", count_of_removals_for_bad_behavior, &result__);
+ impl::WriteJsonField("count_of_tls_error", count_of_tls_error, &result__);
+ impl::WriteJsonField("count_of_run_attempts_while_revoked", count_of_run_attempts_while_revoked, &result__);
return result__;
}
bool AppLevel::is_valid() const {
- if (struct_empty()) {
- return initialization_state__ == kInitialized && Validate();
+ if (!minutes_in_hmi_full.is_valid()) {
+ return false;
+ }
+ if (!app_registration_language_gui.is_valid()) {
+ return false;
+ }
+ if (!app_registration_language_vui.is_valid()) {
+ return false;
+ }
+ if (!minutes_in_hmi_limited.is_valid()) {
+ return false;
+ }
+ if (!minutes_in_hmi_background.is_valid()) {
+ return false;
+ }
+ if (!minutes_in_hmi_none.is_valid()) {
+ return false;
+ }
+ if (!count_of_user_selections.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejections_sync_out_of_memory.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejections_nickname_mismatch.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejections_duplicate_name.is_valid()) {
+ return false;
+ }
+ if (!count_of_rejected_rpc_calls.is_valid()) {
+ return false;
+ }
+ if (!count_of_rpcs_sent_in_hmi_none.is_valid()) {
+ return false;
+ }
+ if (!count_of_removals_for_bad_behavior.is_valid()) {
+ return false;
+ }
+ if (!count_of_tls_error.is_valid()) {
+ return false;
+ }
+ if (!count_of_run_attempts_while_revoked.is_valid()) {
+ return false;
}
return Validate();
}
@@ -952,6 +1043,58 @@ bool AppLevel::is_initialized() const {
return (initialization_state__ != kUninitialized) || (!struct_empty());
}
bool AppLevel::struct_empty() const {
+
+ if (minutes_in_hmi_full.is_initialized()) {
+ return false;
+ }
+ if (app_registration_language_gui.is_initialized()) {
+ return false;
+ }
+
+ if (app_registration_language_vui.is_initialized()) {
+ return false;
+ }
+
+ if (minutes_in_hmi_limited.is_initialized()) {
+ return false;
+ }
+ if (minutes_in_hmi_background.is_initialized()) {
+ return false;
+ }
+
+ if (minutes_in_hmi_none.is_initialized()) {
+ return false;
+ }
+ if (count_of_user_selections.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_rejections_sync_out_of_memory.is_initialized()) {
+ return false;
+ }
+ if (count_of_rejections_nickname_mismatch.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_rejections_duplicate_name.is_initialized()) {
+ return false;
+ }
+ if (count_of_rejected_rpc_calls.is_initialized()) {
+ return false;
+ }
+
+ if (count_of_rpcs_sent_in_hmi_none.is_initialized()) {
+ return false;
+ }
+ if (count_of_removals_for_bad_behavior.is_initialized()) {
+ return false;
+ }
+ if (count_of_tls_error.is_initialized()) {
+ return false;
+ }
+ if (count_of_run_attempts_while_revoked.is_initialized()) {
+ return false;
+ }
return true;
}
void AppLevel::ReportErrors(rpc::ValidationReport* report__) const {
diff --git a/src/components/policy/src/policy/policy_table/table_struct/types.h b/src/components/policy/src/policy/policy_table/table_struct/types.h
index 4896f64a2e..d23d79e2df 100644
--- a/src/components/policy/src/policy/policy_table/table_struct/types.h
+++ b/src/components/policy/src/policy/policy_table/table_struct/types.h
@@ -275,8 +275,26 @@ struct ModuleMeta : CompositeType {
struct AppLevel : CompositeType {
public:
+
+ Integer<uint16_t, 0, 65535> minutes_in_hmi_full;
+ String<1, 10> app_registration_language_gui;
+ String<0, 10> app_registration_language_vui;
+ Integer<uint16_t, 0, 65535> minutes_in_hmi_limited;
+ Integer<uint16_t, 0, 65535> minutes_in_hmi_background;
+ Integer<uint16_t, 0, 65535> minutes_in_hmi_none;
+ Integer<uint16_t, 0, 65535> count_of_user_selections;
+ Integer<uint16_t, 0, 65535> count_of_rejections_sync_out_of_memory;
+ Integer<uint16_t, 0, 65535> count_of_rejections_nickname_mismatch;
+ Integer<uint16_t, 0, 65535> count_of_rejections_duplicate_name;
+ Integer<uint16_t, 0, 65535> count_of_rejected_rpc_calls;
+ Integer<uint16_t, 0, 65535> count_of_rpcs_sent_in_hmi_none;
+ Integer<uint16_t, 0, 65535> count_of_removals_for_bad_behavior;
+ Integer<uint16_t, 0, 65535> count_of_tls_error;
+ Integer<uint16_t, 0, 65535> count_of_run_attempts_while_revoked;
public:
AppLevel();
+ AppLevel(uint16_t minutes_in_hmi_full, const std::string& app_registration_language_gui, const std::string& app_registration_language_vui, uint16_t minutes_in_hmi_limited, uint16_t minutes_in_hmi_background, uint16_t minutes_in_hmi_none, uint16_t count_of_user_selections, uint16_t count_of_rejections_sync_out_of_memory, uint16_t count_of_rejections_nickname_mismatch, uint16_t count_of_rejections_duplicate_name, uint16_t count_of_rejected_rpc_calls, uint16_t count_of_rpcs_sent_in_hmi_none, uint16_t count_of_removals_for_bad_behavior,
+uint16_t count_of_tls_error, uint16_t count_of_run_attempts_while_revoked);
~AppLevel();
explicit AppLevel(const Json::Value* value__);
Json::Value ToJsonValue() const;
diff --git a/src/components/policy/src/policy/src/cache_manager.cc b/src/components/policy/src/policy/src/cache_manager.cc
index 4c8784c703..ac5729b424 100644
--- a/src/components/policy/src/policy/src/cache_manager.cc
+++ b/src/components/policy/src/policy/src/cache_manager.cc
@@ -898,6 +898,48 @@ void CacheManager::Increment(usage_statistics::GlobalCounterId type) {
void CacheManager::Increment(const std::string &app_id,
usage_statistics::AppCounterId type) {
CACHE_MANAGER_CHECK_VOID();
+
+ switch (type) {
+ case usage_statistics::USER_SELECTIONS:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id].
+ count_of_user_selections;
+ break;
+ case usage_statistics::REJECTIONS_SYNC_OUT_OF_MEMORY:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id].
+ count_of_rejections_sync_out_of_memory;
+ break;
+ case usage_statistics::REJECTIONS_NICKNAME_MISMATCH:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id].
+ count_of_rejections_nickname_mismatch;
+ break;
+ case usage_statistics::REJECTIONS_DUPLICATE_NAME:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id].
+ count_of_rejections_duplicate_name;
+ break;
+ case usage_statistics::REJECTED_RPC_CALLS:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id].
+ count_of_rejected_rpc_calls;
+ break;
+ case usage_statistics::RPCS_IN_HMI_NONE:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id].
+ count_of_rpcs_sent_in_hmi_none;
+ break;
+ case usage_statistics::REMOVALS_MISBEHAVED:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id].
+ count_of_removals_for_bad_behavior;
+ break;
+ case usage_statistics::RUN_ATTEMPTS_WHILE_REVOKED:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id].
+ count_of_run_attempts_while_revoked;
+ break;
+ case usage_statistics::COUNT_OF_TLS_ERRORS:
+ ++(*pt_->policy_table.usage_and_error_counts->app_level)[app_id].
+ count_of_tls_error;
+ break;
+ default:
+ LOG4CXX_WARN(logger_, "Type app counter is unknown");
+ return;
+ }
Backup();
}
diff --git a/src/components/policy/src/policy/src/sql_pt_queries.cc b/src/components/policy/src/policy/src/sql_pt_queries.cc
index 44c54040fe..2e2fb92649 100644
--- a/src/components/policy/src/policy/src/sql_pt_queries.cc
+++ b/src/components/policy/src/policy/src/sql_pt_queries.cc
@@ -218,6 +218,7 @@ const std::string kCreateSchema =
" `count_of_rpcs_sent_in_hmi_none` INTEGER DEFAULT 0, "
" `count_of_removals_for_bad_behavior` INTEGER DEFAULT 0, "
" `count_of_run_attempts_while_revoked` INTEGER DEFAULT 0, "
+ " `count_of_tls_errors` INTEGER DEFAULT 0, "
" `app_registration_language_gui` VARCHAR(25), "
" `app_registration_language_vui` VARCHAR(25), "
" CONSTRAINT `fk_app_levels_application1` "
diff --git a/src/components/policy/src/policy/usage_statistics/include/usage_statistics/statistics_manager.h b/src/components/policy/src/policy/usage_statistics/include/usage_statistics/statistics_manager.h
index 3af8f4c195..4226cb7dca 100644
--- a/src/components/policy/src/policy/usage_statistics/include/usage_statistics/statistics_manager.h
+++ b/src/components/policy/src/policy/usage_statistics/include/usage_statistics/statistics_manager.h
@@ -64,7 +64,8 @@ enum AppCounterId {
REJECTED_RPC_CALLS,
RPCS_IN_HMI_NONE,
REMOVALS_MISBEHAVED,
- RUN_ATTEMPTS_WHILE_REVOKED
+ RUN_ATTEMPTS_WHILE_REVOKED,
+ COUNT_OF_TLS_ERRORS,
};
class StatisticsManager {
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc
index a14097b61c..10b42b049f 100644
--- a/src/components/protocol_handler/src/protocol_handler_impl.cc
+++ b/src/components/protocol_handler/src/protocol_handler_impl.cc
@@ -959,7 +959,9 @@ class StartSessionHandler : public security_manager::SecurityManagerListener {
hash_id_(hash_id),
service_type_(service_type) {
}
- bool OnHandshakeDone(const uint32_t connection_key, const bool success) OVERRIDE {
+ bool OnHandshakeDone(
+ const uint32_t connection_key,
+ security_manager::SSLContext::HandshakeResult result) OVERRIDE {
if (connection_key != connection_key_) {
return false;
}
@@ -967,8 +969,7 @@ class StartSessionHandler : public security_manager::SecurityManagerListener {
const bool was_service_protection_enabled =
session_observer_->GetSSLContext(connection_key_, service_type_) != NULL;
if (was_service_protection_enabled) {
- // On Success handshake
- if (success) {
+ if (result != security_manager::SSLContext::Handshake_Result_Success) {
// const std::string error_text("Connection is already protected");
// LOG4CXX_WARN(logger_, error_text << ", key " << connection_key);
// security_manager_->SendInternalError(
@@ -980,11 +981,14 @@ class StartSessionHandler : public security_manager::SecurityManagerListener {
NOTREACHED();
}
} else {
- if (success) {
+ if (result == security_manager::SSLContext::Handshake_Result_Success) {
session_observer_->SetProtectionFlag(connection_key_, service_type_);
}
- protocol_handler_->SendStartSessionAck(connection_id_, session_id_,
- protocol_version_, hash_id_, service_type_, success);
+ protocol_handler_->SendStartSessionAck(
+ connection_id_, session_id_,
+ protocol_version_, hash_id_,
+ service_type_,
+ security_manager::SSLContext::Handshake_Result_Success == result);
}
delete this;
return true;
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 6641050d40..881aefbe81 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
@@ -56,20 +56,26 @@ class CryptoManagerImpl : public CryptoManager {
virtual HandshakeResult DoHandshakeStep(const uint8_t *const in_data,
size_t in_data_size,
const uint8_t** const out_data,
- size_t *out_data_size);
- virtual bool Encrypt(const uint8_t *const in_data, size_t in_data_size,
- const uint8_t ** const out_data, size_t *out_data_size);
- virtual bool Decrypt(const uint8_t *const in_data, size_t in_data_size,
- const uint8_t ** const out_data, size_t *out_data_size);
- virtual bool IsInitCompleted() const;
- virtual bool IsHandshakePending() const;
- virtual size_t get_max_block_size(size_t mtu) const;
- virtual std::string LastError() const;
- virtual ~SSLContextImpl();
-
+ size_t *out_data_size) OVERRIDE;
+ bool Encrypt(const uint8_t *const in_data, size_t in_data_size,
+ const uint8_t ** const out_data, size_t *out_data_size) OVERRIDE;
+ bool Decrypt(const uint8_t *const in_data, size_t in_data_size,
+ const uint8_t ** const out_data, size_t *out_data_size) OVERRIDE;
+ bool IsInitCompleted() const OVERRIDE;
+ bool IsHandshakePending() const OVERRIDE;
+ size_t get_max_block_size(size_t mtu) const OVERRIDE;
+ std::string LastError() const OVERRIDE;
+ void ResetConnection() OVERRIDE;
+ void SetHandshakeContext(const HandshakeContext& hsh_ctx) OVERRIDE;
+ ~SSLContextImpl();
private:
typedef size_t(*BlockSizeGetter)(size_t);
void EnsureBufferSizeEnough(size_t size);
+ void SetHandshakeError(const int error);
+ HandshakeResult openssl_error_convert_to_internal(const long error);
+
+ std::string GetTextBy(X509_NAME* name, int object) const;
+
SSL *connection_;
BIO *bioIn_;
BIO *bioOut_;
@@ -79,9 +85,11 @@ class CryptoManagerImpl : public CryptoManager {
uint8_t *buffer_;
bool is_handshake_pending_;
Mode mode_;
+ mutable std::string last_error_;
BlockSizeGetter max_block_size_;
static std::map<std::string, BlockSizeGetter> max_block_sizes;
static std::map<std::string, BlockSizeGetter> create_max_block_sizes();
+ HandshakeContext hsh_context_;
DISALLOW_COPY_AND_ASSIGN(SSLContextImpl);
};
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 2aa03087eb..37efcf5a5f 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
@@ -148,7 +148,7 @@ class SecurityManagerImpl
* \param success result of connection protection
*/
void NotifyListenersOnHandshakeDone(const uint32_t &connection_key,
- const bool success);
+ SSLContext::HandshakeResult error);
/**
* @brief SecurityConfigSection
* @return Session name in config file
diff --git a/src/components/security_manager/src/security_manager_impl.cc b/src/components/security_manager/src/security_manager_impl.cc
index d985870046..16b63d304c 100644
--- a/src/components/security_manager/src/security_manager_impl.cc
+++ b/src/components/security_manager/src/security_manager_impl.cc
@@ -182,23 +182,31 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) {
"connection is not protected");
LOG4CXX_ERROR(logger_, error_text);
SendInternalError(connection_key, ERROR_INTERNAL, error_text);
- NotifyListenersOnHandshakeDone(connection_key, false);
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Fail);
return;
}
if (ssl_context->IsInitCompleted()) {
- NotifyListenersOnHandshakeDone(connection_key, true);
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Success);
return;
}
+
+ ssl_context->SetHandshakeContext(
+ session_observer_->GetHandshakeContext(connection_key));
+
size_t data_size = 0;
const uint8_t *data = NULL;
+
const security_manager::SSLContext::HandshakeResult result =
ssl_context->StartHandshake(&data, &data_size);
if (security_manager::SSLContext::Handshake_Result_Success != result) {
const std::string error_text("StartHandshake failed, handshake step fail");
LOG4CXX_ERROR(logger_, error_text);
SendInternalError(connection_key, ERROR_INTERNAL, error_text);
- NotifyListenersOnHandshakeDone(connection_key, false);
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Fail);
return;
}
// for client mode will be generated output data
@@ -220,12 +228,13 @@ void SecurityManagerImpl::RemoveListener(SecurityManagerListener *const listener
}
listeners_.remove(listener);
}
-void SecurityManagerImpl::NotifyListenersOnHandshakeDone(const uint32_t &connection_key,
- const bool success) {
+void SecurityManagerImpl::NotifyListenersOnHandshakeDone(
+ const uint32_t &connection_key,
+ SSLContext::HandshakeResult error) {
LOG4CXX_AUTO_TRACE(logger_);
std::list<SecurityManagerListener*>::iterator it = listeners_.begin();
while (it != listeners_.end()) {
- if ((*it)->OnHandshakeDone(connection_key, success)) {
+ if ((*it)->OnHandshakeDone(connection_key, error)) {
// On get notification remove listener
it = listeners_.erase(it);
} else {
@@ -260,7 +269,8 @@ bool SecurityManagerImpl::ProccessHandshakeData(const SecurityMessage &inMessage
LOG4CXX_ERROR(logger_, error_text);
SendInternalError(connection_key, ERROR_SERVICE_NOT_PROTECTED,
error_text, seqNumber);
- NotifyListenersOnHandshakeDone(connection_key, false);
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Fail);
return false;
}
size_t out_data_size;
@@ -274,18 +284,21 @@ bool SecurityManagerImpl::ProccessHandshakeData(const SecurityMessage &inMessage
LOG4CXX_ERROR(logger_, "SendHandshakeData: Handshake failed: " << erorr_text);
SendInternalError(connection_key,
ERROR_SSL_INVALID_DATA, erorr_text, seqNumber);
- NotifyListenersOnHandshakeDone(connection_key, false);
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Fail);
// no handshake data to send
return false;
}
if (sslContext->IsInitCompleted()) {
// On handshake success
LOG4CXX_DEBUG(logger_, "SSL initialization finished success.");
- NotifyListenersOnHandshakeDone(connection_key, true);
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Success);
} else if (handshake_result == SSLContext::Handshake_Result_Fail) {
// On handshake fail
LOG4CXX_WARN(logger_, "SSL initialization finished with fail.");
- NotifyListenersOnHandshakeDone(connection_key, false);
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Fail);
}
if (out_data && out_data_size) {
diff --git a/src/components/security_manager/src/ssl_context_impl.cc b/src/components/security_manager/src/ssl_context_impl.cc
index 09c2efd196..3361711b13 100644
--- a/src/components/security_manager/src/ssl_context_impl.cc
+++ b/src/components/security_manager/src/ssl_context_impl.cc
@@ -37,11 +37,14 @@
#include <openssl/err.h>
#include <memory.h>
#include <map>
+#include <algorithm>
#include "utils/macro.h"
namespace security_manager {
+CREATE_LOGGERPTR_GLOBAL(logger_, "CryptoManagerImpl")
+
CryptoManagerImpl::SSLContextImpl::SSLContextImpl(SSL *conn, Mode mode)
: connection_(conn),
bioIn_(BIO_new(BIO_s_mem())),
@@ -138,19 +141,57 @@ DoHandshakeStep(const uint8_t* const in_data, size_t in_data_size,
DCHECK(out_data_size);
*out_data = NULL;
*out_data_size = 0;
+
// TODO(Ezamakhov): add test - hanshake fail -> restart StartHandshake
sync_primitives::AutoLock locker(bio_locker);
if (SSL_is_init_finished(connection_)) {
is_handshake_pending_ = false;
- return SSLContext::Handshake_Result_Success;
+ return Handshake_Result_Success;
}
if (in_data && in_data_size) {
const int ret = BIO_write(bioIn_, in_data, in_data_size);
if (ret <= 0) {
is_handshake_pending_ = false;
- SSL_clear(connection_);
- return SSLContext::Handshake_Result_AbnormalFail;
+ ResetConnection();
+ return Handshake_Result_AbnormalFail;
+ }
+ }
+
+ bool cn_found;
+ bool sn_found;
+ STACK_OF(X509 ) *peer_certs = SSL_get_peer_cert_chain(connection_);
+ while (sk_X509_num(peer_certs) > 0) {
+ X509* cert = sk_X509_pop(peer_certs);
+ const bool last_step = (sk_X509_num(peer_certs) == 0);
+ X509_NAME* subj_name = X509_get_subject_name(cert);
+ char *subj = X509_NAME_oneline(subj_name, NULL, 0);
+ if (subj) {
+ std::replace(subj, subj + strlen(subj), '/', ' ');
+ LOG4CXX_DEBUG(logger_, "Mobile cert subject:" << subj);
+ OPENSSL_free(subj);
+ }
+ char *issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
+ if (issuer) {
+ std::replace(issuer, issuer + strlen(issuer), '/', ' ');
+ LOG4CXX_DEBUG(logger_, "Mobile cert issuer:" << issuer);
+ OPENSSL_free(issuer);
+ }
+
+ const std::string& cn = GetTextBy(subj_name, NID_commonName);
+ const std::string& sn = GetTextBy(subj_name, NID_serialNumber);
+
+ cn_found = cn_found || (hsh_context_.expected_cn == cn);
+ sn_found = sn_found || (hsh_context_.expected_sn == sn);
+
+ if (!cn_found && last_step) {
+ LOG4CXX_ERROR(logger_,"Trying to run handshake with wrong app name");
+ return Handshake_Result_AppNameMismatch;
+ }
+
+ if (!sn_found && last_step) {
+ LOG4CXX_ERROR(logger_,"Trying to run handshake with wrong app id");
+ return Handshake_Result_AppIDMismatch;
}
}
@@ -166,11 +207,23 @@ DoHandshakeStep(const uint8_t* const in_data, size_t in_data_size,
} else if (handshake_result == 0) {
SSL_clear(connection_);
is_handshake_pending_ = false;
- return SSLContext::Handshake_Result_Fail;
- } else if (SSL_get_error(connection_, handshake_result) != SSL_ERROR_WANT_READ) {
- SSL_clear(connection_);
- is_handshake_pending_ = false;
- return SSLContext::Handshake_Result_AbnormalFail;
+ return Handshake_Result_Fail;
+ } else {
+ const int error = SSL_get_error(connection_, handshake_result);
+ if (error != SSL_ERROR_WANT_READ) {
+ const long error = SSL_get_verify_result(connection_);
+ SetHandshakeError(error);
+ LOG4CXX_WARN(logger_, "Handshake failed with error " << " -> " << SSL_get_error(connection_, error)
+ << " \"" << LastError() << '"');
+ ResetConnection();
+ is_handshake_pending_ = false;
+ // In case error happened but ssl verification shows OK
+ // method will return AbnormalFail.
+ if (X509_V_OK == error) {
+ return Handshake_Result_AbnormalFail;
+ }
+ return openssl_error_convert_to_internal(error);
+ }
}
const size_t pend = BIO_ctrl_pending(bioOut_);
@@ -184,12 +237,12 @@ DoHandshakeStep(const uint8_t* const in_data, size_t in_data_size,
*out_data = buffer_;
} else {
is_handshake_pending_ = false;
- SSL_clear(connection_);
- return SSLContext::Handshake_Result_AbnormalFail;
+ ResetConnection();
+ return Handshake_Result_AbnormalFail;
}
}
- return SSLContext::Handshake_Result_Success;
+ return Handshake_Result_Success;
}
bool CryptoManagerImpl::SSLContextImpl::Encrypt(
@@ -274,6 +327,48 @@ CryptoManagerImpl::SSLContextImpl::~SSLContextImpl() {
delete[] buffer_;
}
+void CryptoManagerImpl::SSLContextImpl::SetHandshakeError(const int error) {
+ const char* error_str = X509_verify_cert_error_string(error);
+ if (error_str) {
+ last_error_ = error_str;
+ } else {
+ // Error will be updated with the next LastError call
+ last_error_.clear();
+ }
+}
+
+void CryptoManagerImpl::SSLContextImpl::ResetConnection() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const int shutdown_result = SSL_shutdown(connection_);
+ if (shutdown_result != 1) {
+ const size_t pend = BIO_ctrl_pending(bioOut_);
+ LOG4CXX_DEBUG(logger_, "Available " << pend << " bytes for shutdown");
+ if (pend > 0) {
+ LOG4CXX_DEBUG(logger_, "Reading shutdown data");
+ EnsureBufferSizeEnough(pend);
+ BIO_read(bioOut_, buffer_, pend);
+ }
+ SSL_shutdown(connection_);
+ }
+ LOG4CXX_DEBUG(logger_, "SSL connection recreation");
+ SSL_CTX * ssl_context = connection_->ctx;
+ SSL_free(connection_);
+ connection_ = SSL_new(ssl_context);
+ if (mode_ == SERVER) {
+ SSL_set_accept_state(connection_);
+ } else {
+ SSL_set_connect_state(connection_);
+ }
+ bioIn_ = BIO_new(BIO_s_mem());
+ bioOut_ = BIO_new(BIO_s_mem());
+ SSL_set_bio(connection_, bioIn_, bioOut_);
+}
+
+void CryptoManagerImpl::SSLContextImpl::SetHandshakeContext(
+ const SSLContext::HandshakeContext& hsh_ctx) {
+ hsh_context_ = hsh_ctx;
+}
+
void CryptoManagerImpl::SSLContextImpl::EnsureBufferSizeEnough(size_t size) {
if (buffer_size_ < size) {
delete[] buffer_;
@@ -281,7 +376,38 @@ void CryptoManagerImpl::SSLContextImpl::EnsureBufferSizeEnough(size_t size) {
if (buffer_) {
buffer_size_ = size;
}
+ }
+}
+
+SSLContext::HandshakeResult
+CryptoManagerImpl::SSLContextImpl::openssl_error_convert_to_internal(
+ const long error) {
+ switch(error) {
+ case X509_V_ERR_CERT_HAS_EXPIRED: return Handshake_Result_CertExpired;
+ case X509_V_ERR_CERT_NOT_YET_VALID: return Handshake_Result_NotYetValid;
+ case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
+ case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ return Handshake_Result_CertNotSigned;
+ default: return Handshake_Result_Fail;
}
}
+std::string CryptoManagerImpl::SSLContextImpl::GetTextBy(
+ X509_NAME* name, int object) const {
+ const int req_len = X509_NAME_get_text_by_NID(name, object, NULL, 0);
+
+ if (-1 == req_len) {
+ return std::string();
+ }
+
+ std::vector<char> data;
+ data.resize(req_len + 1);
+ X509_NAME_get_text_by_NID(name, object, &data.front(), data.size());
+
+ return std::string(data.begin(), data.end() - 1);
+}
+
+
} // namespace security_manager