summaryrefslogtreecommitdiff
path: root/src/components/security_manager/test/security_manager_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/security_manager/test/security_manager_test.cc')
-rw-r--r--src/components/security_manager/test/security_manager_test.cc823
1 files changed, 823 insertions, 0 deletions
diff --git a/src/components/security_manager/test/security_manager_test.cc b/src/components/security_manager/test/security_manager_test.cc
new file mode 100644
index 000000000..30f81ee62
--- /dev/null
+++ b/src/components/security_manager/test/security_manager_test.cc
@@ -0,0 +1,823 @@
+/*
+ * Copyright (c) 2014, 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 <gtest/gtest.h>
+#include <string>
+
+#include "utils/byte_order.h"
+#include "protocol/common.h"
+#include "security_manager/security_manager_impl.h"
+
+#include "protocol_handler_mock.h"
+#include "protocol_observer_mock.h"
+#include "include/security_manager_mock.h"
+#include "transport_manager_mock.h"
+
+// TODO(EZamakhov): add test on get correct/wrong InternalError
+// TODO(EZamakhov): check connection_key the same and seq_number
+// TODO(EZamakhov): check ::SendData with correct query_id and query_type
+
+namespace test {
+namespace components {
+namespace security_manager_test {
+
+using namespace ::protocol_handler;
+using ::protocol_handler::ServiceType;
+using namespace ::transport_manager;
+using namespace ::security_manager;
+
+// Sample data for handshake data emulation
+const int32_t key = 0x1;
+const int32_t seq_number = 0x2;
+const ServiceType secureServiceType = kControl;
+const uint32_t protocolVersion = PROTOCOL_VERSION_2;
+const bool is_final = false;
+
+const uint8_t handshake_data[] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
+const size_t handshake_data_size = sizeof(handshake_data)
+ / sizeof(handshake_data[0]);
+
+uint8_t handshake_data_out[] = { 0x6, 0x7, 0x8 };
+uint8_t *handshake_data_out_pointer = handshake_data_out;
+const size_t handshake_data_out_size = sizeof(handshake_data_out)
+ / sizeof(handshake_data_out[0]);
+
+using ::security_manager::SecurityQuery;
+using security_manager_test::InternalErrorWithErrId;
+using ::testing::Return;
+using ::testing::ReturnNull;
+using ::testing::DoAll;
+using ::testing::SetArgPointee;
+using ::testing::_;
+using ::security_manager::SecurityManager;
+using ::security_manager::SecurityManagerImpl;
+
+class SecurityManagerTest : public ::testing::Test {
+ protected:
+ void SetUp() OVERRIDE {
+ security_manager_.reset(new SecurityManagerImpl());
+ security_manager_->set_session_observer(&mock_session_observer);
+ security_manager_->set_protocol_handler(&mock_protocol_handler);
+ security_manager_->AddListener(&mock_sm_listener);
+ }
+ void TearDown() OVERRIDE {
+ // Wait call methods in thread
+ usleep(100000);
+ }
+
+ void SetMockCryptoManger() {
+ security_manager_->set_crypto_manager(&mock_crypto_manager);
+ }
+ /*
+ * Wrapper for fast emulate recieve SecurityManager::OnMessageReceived
+ */
+ void call_OnMessageReceived(const uint8_t* const data, uint32_t dataSize,
+ const ServiceType serviceType) {
+ const ::protocol_handler::RawMessagePtr rawMessagePtr(
+ new ::protocol_handler::RawMessage(key, protocolVersion, data, dataSize,
+ serviceType));
+ security_manager_->OnMessageReceived(rawMessagePtr);
+ }
+ /*
+ * Wrapper for fast emulate recieve query
+ */
+ void EmulateMobileMessage(SecurityQuery::QueryHeader header,
+ const uint8_t* const data,
+ const uint32_t data_size) {
+ // convert to Big-Endian (network) order
+ const uint32_t query_id = header.query_id << 8;
+ header.query_id = LE_TO_BE32(query_id);
+ header.json_size = LE_TO_BE32(header.json_size);
+ header.seq_number = LE_TO_BE32(header.seq_number);
+
+ const size_t data_sending_size = sizeof(header) + data_size;
+ uint8_t* data_sending = new uint8_t[data_sending_size];
+ memcpy(data_sending, &header, sizeof(header));
+ memcpy(data_sending + sizeof(header), data, data_size);
+
+ call_OnMessageReceived(data_sending, data_sending_size, kControl);
+ delete[] data_sending;
+ }
+ /*
+ * Wrapper for fast emulate recieve Handshake
+ */
+ void EmulateMobileMessageHandShake(const uint8_t* const data,
+ const uint32_t data_size,
+ const int repeat_count = 1) {
+ const SecurityQuery::QueryHeader header(SecurityQuery::NOTIFICATION,
+ SecurityQuery::SEND_HANDSHAKE_DATA,
+ seq_number);
+ for (int c = 0; c < repeat_count; ++c) {
+ 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::SessionObserverMock> mock_session_observer;
+ testing::StrictMock<protocol_handler_test::ProtocolHandlerMock> mock_protocol_handler;
+ testing::StrictMock<security_manager_test::CryptoManagerMock> mock_crypto_manager;
+ testing::StrictMock<security_manager_test::SSLContextMock> mock_ssl_context_new;
+ testing::StrictMock<security_manager_test::SSLContextMock> mock_ssl_context_exists;
+ testing::StrictMock<security_manager_test::SMListenerMock> mock_sm_listener;
+};
+// Test Bodies
+
+/*
+ * SecurityManager shall not set NULL interfaces
+ * 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);
+ security_manager_->AddListener(NULL);
+ // additional check not null config section
+ EXPECT_TRUE(SecurityManagerImpl::ConfigSection());
+}
+/*
+ * Add/Remove NULL listeners do not any additional logics
+ */
+TEST_F(SecurityManagerTest, Listeners_NULL) {
+ security_manager_->AddListener(NULL);
+ security_manager_->RemoveListener(NULL);
+}
+/*
+ * Twice remove listener
+ */
+TEST_F(SecurityManagerTest, Listeners_TwiceRemoveListeners) {
+ security_manager_->RemoveListener(&mock_sm_listener);
+ security_manager_->RemoveListener(&mock_sm_listener);
+}
+/*
+ * Add and remove listeners
+ */
+TEST_F(SecurityManagerTest, Listeners_NoListeners) {
+ // Check correct removing listener
+ security_manager_->RemoveListener(&mock_sm_listener);
+
+ // Expect no calls
+ testing::StrictMock<SMListenerMock> mock_listener2;
+ security_manager_->AddListener(&mock_listener2);
+ security_manager_->RemoveListener(&mock_listener2);
+
+ security_manager_->NotifyListenersOnHandshakeDone(key, true);
+ security_manager_->NotifyListenersOnHandshakeDone(key, false);
+}
+/*
+ * Notifying two listeners
+ */
+TEST_F(SecurityManagerTest, Listeners_Notifying) {
+ // Check correct removing listener
+ security_manager_->RemoveListener(&mock_sm_listener);
+
+ testing::StrictMock<SMListenerMock> mock_listener1;
+ testing::StrictMock<SMListenerMock> mock_listener2;
+
+ const bool first_call_value = true;
+ // Expect call both listeners on 1st call
+ EXPECT_CALL(mock_listener1, OnHandshakeDone(key, first_call_value)).
+ // Emulate false (reject) result
+ WillOnce(Return(false));
+ EXPECT_CALL(mock_listener2, OnHandshakeDone(key, first_call_value)).
+ // Emulate true (accept) result
+ WillOnce(Return(true));
+
+ const bool second_call_value = false;
+ // Expect call last listener on 2d call
+ EXPECT_CALL(mock_listener1, OnHandshakeDone(key, second_call_value)).
+ // Emulate false (reject) result
+ WillOnce(Return(true));
+
+ // Expect no call 3d call
+
+ security_manager_->AddListener(&mock_listener1);
+ security_manager_->AddListener(&mock_listener2);
+ // 1st call
+ security_manager_->NotifyListenersOnHandshakeDone(key, first_call_value);
+ // 2nd call
+ security_manager_->NotifyListenersOnHandshakeDone(key, second_call_value);
+ // 3nd call
+ security_manager_->NotifyListenersOnHandshakeDone(key, false);
+}
+/*
+ * SecurityManager with NULL CryptoManager shall send
+ * InternallError (ERROR_NOT_SUPPORTED) on any Query
+ */
+TEST_F(SecurityManagerTest, SecurityManager_NULLCryptoManager) {
+ // Expect InternalError with ERROR_ID
+ 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, ProtocolVersionUsed(connection_id, session_id,_)).
+ WillOnce(Return(true));
+
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_NOT_SUPPORTED), is_final));
+ const SecurityQuery::QueryHeader header(SecurityQuery::REQUEST,
+ // It could be any query id
+ SecurityQuery::INVALID_QUERY_ID);
+ const uint8_t data = 0;
+ EmulateMobileMessage(header, &data, 1);
+}
+/*
+ * Shall skip all OnMobileMessageSent
+ */
+TEST_F(SecurityManagerTest, OnMobileMessageSent) {
+ const ::protocol_handler::RawMessagePtr rawMessagePtr(
+ new ::protocol_handler::RawMessage(key, protocolVersion, NULL, 0));
+ security_manager_->OnMobileMessageSent(rawMessagePtr);
+}
+/*
+ * Shall skip all not-Secure messages
+ */
+TEST_F(SecurityManagerTest, GetWrongServiceType) {
+ // Call with wrong Service type
+ call_OnMessageReceived(NULL, 0, kRpc);
+ call_OnMessageReceived(NULL, 0, kAudio);
+ call_OnMessageReceived(NULL, 0, kMobileNav);
+ call_OnMessageReceived(NULL, 0, kBulk);
+ call_OnMessageReceived(NULL, 0, kInvalidServiceType);
+}
+/*
+ * Shall send InternallError on null data recieved
+ */
+TEST_F(SecurityManagerTest, GetEmptyQuery) {
+ 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, ProtocolVersionUsed(connection_id, session_id,_)).
+ WillOnce(Return(true));
+
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_INVALID_QUERY_SIZE), is_final));
+ // Call with NULL data
+ call_OnMessageReceived(NULL, 0, secureServiceType);
+}
+/*
+ * Shall send InternallError on null data recieved
+ */
+TEST_F(SecurityManagerTest, GetWrongJSONSize) {
+ SetMockCryptoManger();
+ 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, ProtocolVersionUsed(connection_id, session_id,_)).
+ WillOnce(Return(true));
+ // Expect InternalError with ERROR_ID
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_INVALID_QUERY_SIZE), is_final));
+ SecurityQuery::QueryHeader header(
+ SecurityQuery::REQUEST,
+ SecurityQuery::INVALID_QUERY_ID);
+ header.json_size = 0x0FFFFFFF;
+ EmulateMobileMessage(header, NULL, 0);
+}
+/*
+ * Shall send InternallError on INVALID_QUERY_ID
+ */
+TEST_F(SecurityManagerTest, GetInvalidQueryId) {
+ SetMockCryptoManger();
+ 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, ProtocolVersionUsed(connection_id, session_id,_)).
+ WillOnce(Return(true));
+ // Expect InternalError with ERROR_ID
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_INVALID_QUERY_ID), is_final));
+ const SecurityQuery::QueryHeader header(
+ SecurityQuery::REQUEST,
+ SecurityQuery::INVALID_QUERY_ID);
+ const uint8_t data = 0;
+ EmulateMobileMessage(header, &data, 1);
+}
+/*
+ * Shall send Internall Error on call
+ * CreateSSLContext for already protected connections
+ */
+TEST_F(SecurityManagerTest, CreateSSLContext_ServiceAlreadyProtected) {
+ SetMockCryptoManger();
+
+ // Return mock SSLContext
+ EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)).
+ WillOnce(Return(&mock_ssl_context_new));
+
+ const security_manager::SSLContext* rezult = security_manager_->CreateSSLContext(key);
+ EXPECT_EQ(rezult, &mock_ssl_context_new);
+}
+/*
+ * Shall send Internall Error on error create SSL
+ */
+TEST_F(SecurityManagerTest, CreateSSLContext_ErrorCreateSSL) {
+ SetMockCryptoManger();
+ // Expect InternalError with ERROR_ID
+ 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, ProtocolVersionUsed(connection_id, session_id,_)).
+ WillOnce(Return(true));
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_INTERNAL), is_final));
+
+ // Emulate SessionObserver and CryptoManager result
+ EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)).
+ WillOnce(ReturnNull());
+ EXPECT_CALL(mock_crypto_manager, CreateSSLContext()).
+ WillOnce(ReturnNull());
+
+ const bool rezult = security_manager_->CreateSSLContext(key);
+ EXPECT_FALSE(rezult);
+}
+/*
+ * Shall send InternalError with SERVICE_NOT_FOUND
+ * on getting any Error with call SetSSLContext
+ */
+TEST_F(SecurityManagerTest, CreateSSLContext_SetSSLContextError) {
+ SetMockCryptoManger();
+ // Expect InternalError with ERROR_ID
+ 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, ProtocolVersionUsed(connection_id, session_id,_)).
+ WillOnce(Return(true));
+
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_UNKWOWN_INTERNAL_ERROR), is_final));
+
+ // Emulate SessionObserver and CryptoManager result
+ EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)).
+ WillOnce(ReturnNull());
+ EXPECT_CALL(mock_crypto_manager, CreateSSLContext()).
+ WillOnce(Return(&mock_ssl_context_new));
+ EXPECT_CALL(mock_crypto_manager, ReleaseSSLContext(&mock_ssl_context_new));
+ EXPECT_CALL(mock_session_observer, SetSSLContext(key, &mock_ssl_context_new)).
+ WillOnce(Return(SecurityManager::ERROR_UNKWOWN_INTERNAL_ERROR));
+
+ const bool rezult = security_manager_->CreateSSLContext(key);
+ EXPECT_FALSE(rezult);
+}
+/*
+ * Shall protect connection on correct call CreateSSLContext
+ */
+TEST_F(SecurityManagerTest, CreateSSLContext_Success) {
+ SetMockCryptoManger();
+ // Expect no Errors
+ // Expect no notifying listeners - it will be done after handshake
+
+ // 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));
+ EXPECT_CALL(mock_crypto_manager, CreateSSLContext()).
+ WillOnce(Return(&mock_ssl_context_new));
+ EXPECT_CALL(mock_session_observer, SetSSLContext(key, &mock_ssl_context_new)).
+ WillOnce(Return(SecurityManager::ERROR_SUCCESS));
+
+ const bool rezult = security_manager_->CreateSSLContext(key);
+ EXPECT_TRUE(rezult);
+}
+/*
+ * Shall send InternallError on call StartHandshake for uprotected service
+ */
+TEST_F(SecurityManagerTest, StartHandshake_ServiceStillUnprotected) {
+ SetMockCryptoManger();
+ 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, ProtocolVersionUsed(connection_id, session_id,_)).
+ WillOnce(Return(true));
+ // Expect InternalError with ERROR_INTERNAL
+ EXPECT_CALL(mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_INTERNAL), is_final));
+ // Expect notifying listeners (unsuccess)
+ EXPECT_CALL(mock_sm_listener, OnHandshakeDone(key, false)).WillOnce(Return(true));
+
+ // Emulate SessionObserver result
+ EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)).
+ WillOnce(ReturnNull());
+
+ security_manager_->StartHandshake(key);
+}
+/*
+ * Shall send InternallError on SSL error and notify listeners
+ */
+TEST_F(SecurityManagerTest, StartHandshake_SSLInternalError) {
+ SetMockCryptoManger();
+
+ 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, 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, false)).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, StartHandshake(_, _)).
+ WillOnce(DoAll(SetArgPointee<0>(handshake_data_out_pointer),
+ SetArgPointee<1>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Fail)));
+
+ security_manager_->StartHandshake(key);
+}
+/*
+ * Shall send data on call StartHandshake
+ */
+TEST_F(SecurityManagerTest, StartHandshake_SSLInitIsNotComplete) {
+ SetMockCryptoManger();
+ 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, 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));
+
+ // 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(security_manager::SSLContext::
+ Handshake_Result_Success))).
+ WillOnce(DoAll(SetArgPointee<0>((uint8_t*)NULL),
+ SetArgPointee<1>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Success))).
+ WillOnce(DoAll(SetArgPointee<0>(handshake_data_out_pointer),
+ SetArgPointee<1>(handshake_data_out_size),
+ Return(security_manager::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) {
+ SetMockCryptoManger();
+ // Expect no message send
+ // Expect notifying listeners (success)
+ EXPECT_CALL(mock_sm_listener, OnHandshakeDone(key, true)).
+ 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);
+}
+/*
+ * Shall send InternallError on
+ * getting SEND_HANDSHAKE_DATA with NULL data
+ */
+TEST_F(SecurityManagerTest, ProccessHandshakeData_WrongDataSize) {
+ SetMockCryptoManger();
+ 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, ProtocolVersionUsed(connection_id, session_id,_)).
+ WillOnce(Return(true));
+
+ // Expect InternalError with ERROR_ID
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_INVALID_QUERY_SIZE), is_final));
+ EmulateMobileMessageHandShake(NULL, 0);
+}
+/*
+ * Shall send InternallError on
+ * getting SEND_HANDSHAKE_DATA from mobile side
+ * for service which is not protected
+ */
+TEST_F(SecurityManagerTest, ProccessHandshakeData_ServiceNotProtected) {
+ SetMockCryptoManger();
+ // Expect InternalError with ERROR_ID
+ 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, ProtocolVersionUsed(connection_id, session_id,_)).
+ WillOnce(Return(true));
+
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_SERVICE_NOT_PROTECTED), is_final));
+ // Expect notifying listeners (unsuccess)
+ EXPECT_CALL(mock_sm_listener, OnHandshakeDone(key, false)).
+ WillOnce(Return(true));
+
+ // Emulate SessionObserver result
+ EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)).
+ WillOnce(ReturnNull());
+
+ const uint8_t data[] = {0x1, 0x2};
+ EmulateMobileMessageHandShake(data, sizeof(data)/sizeof(data[0]));
+}
+/*
+ * Shall send InternallError on getting
+ * SEND_HANDSHAKE_DATA from mobile side with invalid handshake
+ * data (DoHandshakeStep return NULL pointer)
+ */
+TEST_F(SecurityManagerTest, ProccessHandshakeData_InvalidData) {
+ SetMockCryptoManger();
+
+ // Count handshake calls
+ const int handshake_emulates = 4;
+
+ uint32_t connection_id = 0;
+ uint8_t session_id = 0;
+ //uint8_t protocol_version = 0;
+ EXPECT_CALL(mock_session_observer, PairFromKey(key, _, _)).
+ Times(handshake_emulates);
+ EXPECT_CALL(mock_session_observer, ProtocolVersionUsed(connection_id, session_id,_)).
+ Times(handshake_emulates).
+ WillRepeatedly(Return(true));
+
+ // Expect InternalError with ERROR_ID
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_SSL_INVALID_DATA), is_final)).
+ Times(handshake_emulates);
+ // Expect notifying listeners (unsuccess)
+ EXPECT_CALL(mock_sm_listener, OnHandshakeDone(key, false)).
+ WillOnce(Return(true));
+
+ // Emulate SessionObserver and CryptoManager result
+ EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)).
+ Times(handshake_emulates).
+ WillRepeatedly(Return(&mock_ssl_context_exists));
+ // Emulate DoHandshakeStep fail logics
+ EXPECT_CALL(
+ mock_ssl_context_exists, DoHandshakeStep(_, handshake_data_size, _, _)).
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_AbnormalFail))).
+ WillOnce(DoAll(SetArgPointee<2>((uint8_t*)NULL),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_AbnormalFail))).
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(0),
+ Return(security_manager::SSLContext::
+ Handshake_Result_AbnormalFail))).
+ WillOnce(DoAll(SetArgPointee<2>((uint8_t*)NULL),
+ SetArgPointee<3>(0),
+ Return(security_manager::SSLContext::
+ Handshake_Result_AbnormalFail)));
+
+
+ // On each wrong handshake will be asked error
+ EXPECT_CALL(mock_ssl_context_exists, LastError()).
+ Times(handshake_emulates);
+
+ // Emulate handshare #handshake_emulates times for 5 cases
+ EmulateMobileMessageHandShake(handshake_data, handshake_data_size,
+ handshake_emulates);
+}
+/*
+ * Shall send HandshakeData on getting SEND_HANDSHAKE_DATA from mobile side
+ * with correct handshake data Check Fail and sussecc states
+ */
+TEST_F(SecurityManagerTest, ProccessHandshakeData_Answer) {
+ SetMockCryptoManger();
+ // Count handshake calls
+ const int handshake_emulates = 2;
+
+ uint32_t connection_id = 0;
+ uint8_t session_id = 0;
+ //uint8_t protocol_version = 0;
+ EXPECT_CALL(mock_session_observer, PairFromKey(key, _, _)).
+ Times(handshake_emulates);
+ EXPECT_CALL(mock_session_observer, ProtocolVersionUsed(connection_id, session_id,_)).
+ Times(handshake_emulates).
+ WillRepeatedly(Return(true));
+
+ // Expect InternalError with ERROR_ID
+ EXPECT_CALL(mock_protocol_handler, SendMessageToMobileApp(
+ // FIXME : !!!
+ _, is_final)).
+ Times(handshake_emulates);
+ // Expect notifying listeners (unsuccess)
+ EXPECT_CALL(mock_sm_listener, OnHandshakeDone(key, false)).
+ WillOnce(Return(true));
+
+ // Emulate SessionObserver and CryptoManager result
+ EXPECT_CALL(mock_ssl_context_exists, IsInitCompleted()).
+ Times(handshake_emulates).
+ WillRepeatedly(Return(false));
+ EXPECT_CALL(
+ mock_session_observer, GetSSLContext(key, kControl)).
+ Times(handshake_emulates).
+ WillRepeatedly(Return(&mock_ssl_context_exists));
+
+ // Emulate DoHandshakeStep correct logics
+ EXPECT_CALL(
+ mock_ssl_context_exists, DoHandshakeStep(_, handshake_data_size, _, _)).
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Success))).
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Fail)));
+
+ EmulateMobileMessageHandShake(handshake_data, handshake_data_size,
+ handshake_emulates);
+}
+/*
+ * Shall call all listeners on success end handshake
+ * and return handshake data
+ * Check Fail and sussecc states
+ */
+TEST_F(SecurityManagerTest, ProccessHandshakeData_HandShakeFinished) {
+ SetMockCryptoManger();
+ // Count handshake calls
+ const int handshake_emulates = 6;
+ // Expect no errors
+ // Expect notifying listeners (success)
+ EXPECT_CALL(mock_sm_listener, OnHandshakeDone(key, true)).
+ WillOnce(Return(true));
+
+ // Emulate SessionObserver and CryptoManager result
+ EXPECT_CALL(
+ mock_session_observer, GetSSLContext(key, kControl)).
+ Times(handshake_emulates).
+ WillRepeatedly(Return(&mock_ssl_context_exists));
+ EXPECT_CALL(
+ mock_ssl_context_exists, IsInitCompleted()).
+ Times(handshake_emulates).
+ WillRepeatedly(Return(true));
+ // FIXME(EZamakhov): add DoHandshakeStep matcher for compare handshake data
+ EXPECT_CALL(
+ mock_ssl_context_exists, DoHandshakeStep(_, handshake_data_size, _, _)).
+ // two states with correct out data
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Success))).
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Fail))).
+ // two states with with null pointer data
+ WillOnce(DoAll(SetArgPointee<2>((uint8_t*)NULL),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Success))).
+ WillOnce(DoAll(SetArgPointee<2>((uint8_t*)NULL),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Fail))).
+ // two states with with null data size
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(0),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Success))).
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(0),
+ Return(security_manager::SSLContext::
+ Handshake_Result_Success)));
+
+ // Expect send two message (with correct pointer and size data)
+
+ uint32_t connection_id = 0;
+ uint8_t session_id = 0;
+ //uint8_t protocol_version = 0;
+ EXPECT_CALL(mock_session_observer, PairFromKey(key, _, _)).
+ Times(2);
+ EXPECT_CALL(mock_session_observer, ProtocolVersionUsed(connection_id, session_id,_)).
+ Times(2).
+ WillRepeatedly(Return(true));
+
+ EXPECT_CALL(
+ mock_protocol_handler, SendMessageToMobileApp(_, is_final)).
+ Times(2);
+
+ // Expect NO InternalError with ERROR_ID
+ EmulateMobileMessageHandShake(handshake_data, handshake_data_size, handshake_emulates);
+}
+/*
+ * Shall not any query on getting empty SEND_INTERNAL_ERROR
+ */
+TEST_F(SecurityManagerTest, GetInternalError_NullData) {
+ SetMockCryptoManger();
+
+ const SecurityQuery::QueryHeader header( SecurityQuery::NOTIFICATION,
+ SecurityQuery::SEND_INTERNAL_ERROR, 0);
+ EmulateMobileMessage(header, NULL, 0);
+}
+/*
+ * Shall not send any query on getting SEND_INTERNAL_ERROR
+ */
+TEST_F(SecurityManagerTest, GetInternalError) {
+ SetMockCryptoManger();
+
+ const SecurityQuery::QueryHeader header( SecurityQuery::NOTIFICATION,
+ SecurityQuery::SEND_INTERNAL_ERROR, 0);
+ const uint8_t data[] = {0x1, 0x2};
+ EmulateMobileMessage(header, data, sizeof(data)/sizeof(data[0]));
+}
+/*
+ * Shall not send any query on getting SEND_INTERNAL_ERROR with error string
+ */
+TEST_F(SecurityManagerTest, GetInternalError_WithErrText) {
+ SetMockCryptoManger();
+
+ SecurityQuery::QueryHeader header( SecurityQuery::NOTIFICATION,
+ SecurityQuery::SEND_INTERNAL_ERROR, 0);
+ std::string error("JSON wrong string");
+ header.json_size = error.size();
+ EmulateMobileMessage(header,
+ reinterpret_cast<const uint8_t*>(error.c_str()),
+ error.size());
+}
+/*
+ * Shall not send any query on getting SEND_INTERNAL_ERROR with error string
+ */
+TEST_F(SecurityManagerTest, GetInternalError_WithErrJSONText) {
+ SetMockCryptoManger();
+
+ SecurityQuery::QueryHeader header( SecurityQuery::NOTIFICATION,
+ SecurityQuery::SEND_INTERNAL_ERROR, 0);
+ std::string error(" { \"id\": 1 } ");
+ header.json_size = error.size();
+ EmulateMobileMessage(header,
+ reinterpret_cast<const uint8_t*>(error.c_str()),
+ error.size());
+}
+
+} // namespace security_manager_test
+} // namespace components
+} // namespace test