summaryrefslogtreecommitdiff
path: root/src/components/protocol_handler
diff options
context:
space:
mode:
authorJacob Keeler <jacob.keeler@livioradio.com>2018-06-18 12:01:38 -0700
committerGitHub <noreply@github.com>2018-06-18 12:01:38 -0700
commit9c6a43aad481a1b45a50ccc40b456bb168989f47 (patch)
treecf21b340a414c183d92c733091e159390186022b /src/components/protocol_handler
parent28c8a64c67b137508bfc1b9ec35b6723fae992db (diff)
parent24edd97c1f2b4fc67eb882245cd865939b075c6f (diff)
downloadsdl_core-9c6a43aad481a1b45a50ccc40b456bb168989f47.tar.gz
Merge branch 'develop' into feat/mt_transport_changes
Diffstat (limited to 'src/components/protocol_handler')
-rw-r--r--src/components/protocol_handler/include/protocol_handler/handshake_handler.h6
-rw-r--r--src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h4
-rw-r--r--src/components/protocol_handler/include/protocol_handler/protocol_packet.h6
-rw-r--r--src/components/protocol_handler/src/handshake_handler.cc12
-rw-r--r--src/components/protocol_handler/src/multiframe_builder.cc2
-rw-r--r--src/components/protocol_handler/src/protocol_handler_impl.cc62
-rw-r--r--src/components/protocol_handler/src/protocol_packet.cc24
-rw-r--r--src/components/protocol_handler/test/protocol_handler_tm_test.cc49
8 files changed, 128 insertions, 37 deletions
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 020754608b..5b62a54c22 100644
--- a/src/components/protocol_handler/include/protocol_handler/handshake_handler.h
+++ b/src/components/protocol_handler/include/protocol_handler/handshake_handler.h
@@ -91,6 +91,12 @@ class HandshakeHandler : public security_manager::SecurityManagerListener {
security_manager::SSLContext::HandshakeResult result) OVERRIDE;
/**
+ * @brief Notification about handshake failure
+ * @return true on success notification handling or false otherwise
+ */
+ bool 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 d5f498df6d..765260c675 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
@@ -267,6 +267,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
@@ -790,7 +792,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/include/protocol_handler/protocol_packet.h b/src/components/protocol_handler/include/protocol_handler/protocol_packet.h
index e5b1e3360d..d3e3ec5809 100644
--- a/src/components/protocol_handler/include/protocol_handler/protocol_packet.h
+++ b/src/components/protocol_handler/include/protocol_handler/protocol_packet.h
@@ -252,6 +252,12 @@ class ProtocolPacket {
const size_t messageSize);
/**
+ * @brief Calculates FIRST_FRAME data for further handling of consecutive
+ * frames
+ */
+ void HandleRawFirstFrameData(const uint8_t* message);
+
+ /**
* \brief Getter of protocol version.
*/
uint8_t protocol_version() const;
diff --git a/src/components/protocol_handler/src/handshake_handler.cc b/src/components/protocol_handler/src/handshake_handler.cc
index 46b80db29e..2fc229cb1b 100644
--- a/src/components/protocol_handler/src/handshake_handler.cc
+++ b/src/components/protocol_handler/src/handshake_handler.cc
@@ -94,6 +94,18 @@ bool HandshakeHandler::GetPolicyCertificateData(std::string& data) const {
void HandshakeHandler::OnCertificateUpdateRequired() {}
+bool 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);
+ return true;
+}
+
bool HandshakeHandler::OnHandshakeDone(
uint32_t connection_key,
security_manager::SSLContext::HandshakeResult result) {
diff --git a/src/components/protocol_handler/src/multiframe_builder.cc b/src/components/protocol_handler/src/multiframe_builder.cc
index 5a1fc6d205..cf8a23ddc1 100644
--- a/src/components/protocol_handler/src/multiframe_builder.cc
+++ b/src/components/protocol_handler/src/multiframe_builder.cc
@@ -91,6 +91,8 @@ bool MultiFrameBuilder::RemoveConnection(const ConnectionID connection_id) {
ProtocolFramePtrList MultiFrameBuilder::PopMultiframes() {
LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_DEBUG(logger_, "Current state is: " << multiframes_map_);
+ LOG4CXX_DEBUG(logger_,
+ "Current multiframe map size is: " << multiframes_map_.size());
ProtocolFramePtrList outpute_frame_list;
for (MultiFrameMap::iterator connection_it = multiframes_map_.begin();
connection_it != multiframes_map_.end();
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc
index 04a7237e45..d74348b32d 100644
--- a/src/components/protocol_handler/src/protocol_handler_impl.cc
+++ b/src/components/protocol_handler/src/protocol_handler_impl.cc
@@ -152,6 +152,7 @@ ProtocolHandlerImpl::~ProtocolHandlerImpl() {
"Not all observers have unsubscribed"
" from ProtocolHandlerImpl");
}
+ handshake_handlers_.clear();
}
void ProtocolHandlerImpl::AddProtocolObserver(ProtocolObserver* observer) {
@@ -1091,6 +1092,11 @@ void ProtocolHandlerImpl::OnUnexpectedDisconnect(
OnConnectionClosed(connection_id);
}
+void ProtocolHandlerImpl::NotifyOnFailedHandshake() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ security_manager_->NotifyListenersOnHandshakeFailed();
+}
+
void ProtocolHandlerImpl::OnPTUFinished(const bool ptu_result) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -1103,12 +1109,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");
@@ -1623,7 +1631,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);
@@ -1753,11 +1762,11 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession(
}
#ifdef ENABLE_SECURITY
+ const uint8_t protocol_version = packet->protocol_version();
const bool protection =
- // Protocol version 1 is not support protection
- (packet->protocol_version() > PROTOCOL_VERSION_1)
- ? packet->protection_flag()
- : false;
+ // Protocol version 1 does not support protection
+ (protocol_version > PROTOCOL_VERSION_1) ? packet->protection_flag()
+ : false;
#else
const bool protection = false;
#endif // ENABLE_SECURITY
@@ -1950,14 +1959,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 "
@@ -1973,6 +1979,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);
@@ -1981,9 +1988,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);
@@ -2017,12 +2026,27 @@ void ProtocolHandlerImpl::NotifySessionStarted(
*fullVersion,
*start_session_ack_params);
} else {
- security_manager_->AddListener(new HandshakeHandler(*handler));
+ LOG4CXX_DEBUG(logger_,
+ "Adding Handshake handler to listeners: " << handler.get());
+ security_manager::SecurityManagerListener* listener =
+ new HandshakeHandler(*handler);
+ security_manager_->AddListener(listener);
+
if (!ssl_context->IsHandshakePending()) {
// Start handshake process
security_manager_->StartHandshake(connection_key);
+
+ if (!security_manager_->IsSystemTimeProviderReady()) {
+ security_manager_->RemoveListener(listener);
+ SendStartSessionNAck(context.connection_id_,
+ packet->session_id(),
+ protocol_version,
+ packet->service_type(),
+ rejected_params);
+ }
}
}
+
LOG4CXX_DEBUG(logger_,
"Protection establishing for connection "
<< connection_key << " is in progress");
@@ -2075,6 +2099,7 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageHeartBeat(
}
void ProtocolHandlerImpl::PopValideAndExpirateMultiframes() {
+ LOG4CXX_AUTO_TRACE(logger_);
const ProtocolFramePtrList& frame_list = multiframe_builder_.PopMultiframes();
for (ProtocolFramePtrList::const_iterator it = frame_list.begin();
it != frame_list.end();
@@ -2321,6 +2346,11 @@ RESULT_CODE ProtocolHandlerImpl::DecryptFrame(ProtocolFramePtr packet) {
<< out_data_size << " bytes");
DCHECK(out_data);
DCHECK(out_data_size);
+ // Special handling for decrypted FIRST_FRAME
+ if (packet->frame_type() == FRAME_TYPE_FIRST && packet->protection_flag()) {
+ packet->HandleRawFirstFrameData(out_data);
+ return RESULT_OK;
+ }
packet->set_data(out_data, out_data_size);
return RESULT_OK;
}
diff --git a/src/components/protocol_handler/src/protocol_packet.cc b/src/components/protocol_handler/src/protocol_packet.cc
index 065fd97aa0..3cd9e7f781 100644
--- a/src/components/protocol_handler/src/protocol_packet.cc
+++ b/src/components/protocol_handler/src/protocol_packet.cc
@@ -524,6 +524,17 @@ bool ProtocolPacket::operator==(const ProtocolPacket& other) const {
return false;
}
+void ProtocolPacket::HandleRawFirstFrameData(const uint8_t* message) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ payload_size_ = 0;
+ const uint8_t* data = message;
+ uint32_t total_data_bytes = data[0] << 24;
+ total_data_bytes |= data[1] << 16;
+ total_data_bytes |= data[2] << 8;
+ total_data_bytes |= data[3];
+ set_total_data_bytes(total_data_bytes);
+}
+
RESULT_CODE ProtocolPacket::deserializePacket(const uint8_t* message,
const size_t messageSize) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -536,18 +547,15 @@ RESULT_CODE ProtocolPacket::deserializePacket(const uint8_t* message,
packet_data_.totalDataBytes = packet_header_.dataSize;
uint32_t dataPayloadSize = 0;
- if ((offset < messageSize) && packet_header_.frameType != FRAME_TYPE_FIRST) {
+ if ((offset < messageSize)) {
dataPayloadSize = messageSize - offset;
}
- if (packet_header_.frameType == FRAME_TYPE_FIRST) {
+ if (packet_header_.frameType == FRAME_TYPE_FIRST &&
+ !packet_header_.protection_flag) {
payload_size_ = 0;
const uint8_t* data = message + offset;
- uint32_t total_data_bytes = data[0] << 24;
- total_data_bytes |= data[1] << 16;
- total_data_bytes |= data[2] << 8;
- total_data_bytes |= data[3];
- set_total_data_bytes(total_data_bytes);
+ HandleRawFirstFrameData(data);
if (0 == packet_data_.data) {
return RESULT_FAIL;
}
@@ -606,6 +614,8 @@ uint8_t* ProtocolPacket::data() const {
}
void ProtocolPacket::set_total_data_bytes(size_t dataBytes) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Data bytes : " << dataBytes);
if (dataBytes) {
delete[] packet_data_.data;
packet_data_.data = new (std::nothrow) uint8_t[dataBytes];
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 7b47084c60..b73fbf7f5f 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>
@@ -99,8 +100,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
@@ -1011,7 +1016,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()));
@@ -1066,7 +1074,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(
@@ -1143,7 +1151,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));
@@ -1222,7 +1230,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(
@@ -1320,7 +1328,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(
@@ -1416,7 +1424,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(
@@ -1444,27 +1455,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(