summaryrefslogtreecommitdiff
path: root/src/components/security_manager
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/security_manager')
-rw-r--r--src/components/security_manager/CMakeLists.txt4
-rw-r--r--src/components/security_manager/include/security_manager/crypto_manager_impl.h95
-rw-r--r--src/components/security_manager/include/security_manager/crypto_manager_settings_impl.h65
-rw-r--r--src/components/security_manager/include/security_manager/security_manager_impl.h76
-rw-r--r--src/components/security_manager/include/security_manager/security_query.h186
-rw-r--r--src/components/security_manager/src/crypto_manager_impl.cc360
-rw-r--r--src/components/security_manager/src/security_manager_impl.cc250
-rw-r--r--src/components/security_manager/src/security_query.cc97
-rw-r--r--src/components/security_manager/src/ssl_context_impl.cc423
-rw-r--r--src/components/security_manager/test/CMakeLists.txt20
-rw-r--r--src/components/security_manager/test/crypto_manager_impl_test.cc588
-rw-r--r--src/components/security_manager/test/include/security_manager_mock.h311
-rw-r--r--src/components/security_manager/test/mycert.pem22
-rw-r--r--src/components/security_manager/test/mykey.pem27
-rw-r--r--src/components/security_manager/test/security_manager_test.cc774
-rw-r--r--src/components/security_manager/test/security_query_matcher.cc84
-rw-r--r--src/components/security_manager/test/security_query_test.cc101
-rw-r--r--src/components/security_manager/test/ssl_certificate_handshake_test.cc583
-rw-r--r--src/components/security_manager/test/ssl_context_test.cc535
19 files changed, 2865 insertions, 1736 deletions
diff --git a/src/components/security_manager/CMakeLists.txt b/src/components/security_manager/CMakeLists.txt
index 6973a98e07..3cc6178931 100644
--- a/src/components/security_manager/CMakeLists.txt
+++ b/src/components/security_manager/CMakeLists.txt
@@ -33,7 +33,9 @@ include_directories(
include/
${COMPONENTS_DIR}/protocol_handler/include/
${COMPONENTS_DIR}/connection_handler/include
+ ${COMPONENTS_DIR}/config_profile/include/
${COMPONENTS_DIR}/utils/include/
+ ${COMPONENTS_DIR}/application_manager/include/
${JSONCPP_INCLUDE_DIRECTORY}
${CMAKE_SOURCE_DIR}/src/thirdPartyLibs/jsoncpp/include
${APR_INCLUDE_DIRECTORY}
@@ -51,4 +53,4 @@ target_link_libraries(SecurityManager crypto ssl ProtocolHandler jsoncpp Protoco
if(BUILD_TESTS)
add_subdirectory(test)
-endif() \ No newline at end of file
+endif()
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 43bb63ef67..6aea2e28b1 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
@@ -42,66 +42,97 @@
#include "security_manager/crypto_manager.h"
#include "security_manager/ssl_context.h"
+#include "security_manager/security_manager_settings.h"
+
#include "utils/macro.h"
#include "utils/lock.h"
+#include "utils/shared_ptr.h"
namespace security_manager {
class CryptoManagerImpl : public CryptoManager {
private:
class SSLContextImpl : public SSLContext {
public:
- SSLContextImpl(SSL *conn, Mode mode);
+ SSLContextImpl(SSL* conn, Mode mode, size_t maximum_payload_size);
+ ~SSLContextImpl();
virtual HandshakeResult StartHandshake(const uint8_t** const out_data,
- size_t *out_data_size);
- virtual HandshakeResult DoHandshakeStep(const uint8_t *const in_data,
+ size_t* out_data_size);
+ 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;
+
+ void PrintCertData(X509* cert, const std::string& cert_owner);
private:
- typedef size_t(*BlockSizeGetter)(size_t);
+ void PrintCertInfo();
+ HandshakeResult CheckCertContext();
+ bool ReadHandshakeData(const uint8_t** const out_data,
+ size_t* out_data_size);
+ bool WriteHandshakeData(const uint8_t* const in_data, size_t in_data_size);
+ HandshakeResult PerformHandshake();
+ typedef size_t (*BlockSizeGetter)(size_t);
void EnsureBufferSizeEnough(size_t size);
- SSL *connection_;
- BIO *bioIn_;
- BIO *bioOut_;
- BIO *bioFilter_;
+ 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_;
+ BIO* bioFilter_;
mutable sync_primitives::Lock bio_locker;
size_t buffer_size_;
- uint8_t *buffer_;
+ 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);
};
public:
- CryptoManagerImpl();
- virtual bool Init(Mode mode,
- Protocol protocol,
- const std::string &cert_filename,
- const std::string &key_filename,
- const std::string &ciphers_list,
- bool verify_peer);
- virtual void Finish();
- virtual SSLContext *CreateSSLContext();
- virtual void ReleaseSSLContext(SSLContext *context);
- virtual std::string LastError() const;
+ explicit CryptoManagerImpl(
+ const utils::SharedPtr<const CryptoManagerSettings> set);
+ ~CryptoManagerImpl();
+
+ bool Init() OVERRIDE;
+ bool OnCertificateUpdated(const std::string& data) OVERRIDE;
+ SSLContext* CreateSSLContext() OVERRIDE;
+ void ReleaseSSLContext(SSLContext* context) OVERRIDE;
+ std::string LastError() const OVERRIDE;
+ virtual bool IsCertificateUpdateRequired() const OVERRIDE;
+ virtual const CryptoManagerSettings& get_settings() const OVERRIDE;
private:
- SSL_CTX *context_;
- Mode mode_;
+ 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);
+
+ const utils::SharedPtr<const CryptoManagerSettings> settings_;
+ SSL_CTX* context_;
+ mutable struct tm expiration_time_;
static uint32_t instance_count_;
+ static sync_primitives::Lock instance_lock_;
DISALLOW_COPY_AND_ASSIGN(CryptoManagerImpl);
};
} // namespace security_manager
diff --git a/src/components/security_manager/include/security_manager/crypto_manager_settings_impl.h b/src/components/security_manager/include/security_manager/crypto_manager_settings_impl.h
new file mode 100644
index 0000000000..1e4699b77a
--- /dev/null
+++ b/src/components/security_manager/include/security_manager/crypto_manager_settings_impl.h
@@ -0,0 +1,65 @@
+
+#ifndef SRC_COMPONENTS_SECURITY_MANAGER_INCLUDE_SECURITY_MANAGER_CRYPTO_MANAGER_SETTINGS_IMPL_H_
+#define SRC_COMPONENTS_SECURITY_MANAGER_INCLUDE_SECURITY_MANAGER_CRYPTO_MANAGER_SETTINGS_IMPL_H_
+#include "security_manager/security_manager_settings.h"
+#include "config_profile/profile.h"
+
+namespace security_manager {
+
+class CryptoManagerSettingsImpl : public CryptoManagerSettings {
+ public:
+ CryptoManagerSettingsImpl(const profile::Profile& profile,
+ const std::string& certificate_data)
+ : profile_(profile), certificate_data_(certificate_data) {}
+
+ // CryptoManagerSettings interface
+ Mode security_manager_mode() const OVERRIDE {
+ return profile_.ssl_mode() == "SERVER" ? security_manager::SERVER
+ : security_manager::CLIENT;
+ }
+ Protocol security_manager_protocol_name() const OVERRIDE {
+ CREATE_LOGGERPTR_LOCAL(logger_, "SecurityManager")
+
+ const std::string& protocol_str = profile_.security_manager_protocol_name();
+ if (protocol_str == "TLSv1.0") {
+ return security_manager::TLSv1;
+ }
+ if (protocol_str == "TLSv1.1") {
+ return security_manager::TLSv1_1;
+ }
+ if (protocol_str == "TLSv1.2") {
+ return security_manager::TLSv1_2;
+ }
+ if (protocol_str == "SSLv3") {
+ return security_manager::SSLv3;
+ }
+ LOG4CXX_ERROR(
+ logger_,
+ "Unknown protocol: " << profile_.security_manager_protocol_name());
+ return static_cast<security_manager::Protocol>(-1);
+ }
+ bool verify_peer() const OVERRIDE {
+ return profile_.verify_peer();
+ }
+ const std::string& certificate_data() const OVERRIDE {
+ return certificate_data_;
+ }
+ const std::string& ciphers_list() const OVERRIDE {
+ return profile_.ciphers_list();
+ }
+ const std::string& ca_cert_path() const OVERRIDE {
+ return profile_.ca_cert_path();
+ }
+ size_t update_before_hours() const OVERRIDE {
+ return profile_.update_before_hours();
+ }
+ size_t maximum_payload_size() const OVERRIDE {
+ return profile_.maximum_payload_size();
+ }
+
+ private:
+ const profile::Profile& profile_;
+ const std::string certificate_data_;
+};
+}
+#endif // SRC_COMPONENTS_SECURITY_MANAGER_INCLUDE_SECURITY_MANAGER_CRYPTO_MANAGER_SETTINGS_IMPL_H_
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..d4231ffaa0 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
@@ -51,9 +51,10 @@ namespace security_manager {
* \brief SecurityMessageQueue and SecurityMessageLoop are support typedefs
* for thread working
*/
-struct SecurityMessage: public SecurityQueryPtr {
- explicit SecurityMessage(const SecurityQueryPtr &message)
- : SecurityQueryPtr(message) {}
+struct SecurityMessage : public SecurityQueryPtr {
+ SecurityMessage() {}
+ explicit SecurityMessage(const SecurityQueryPtr& message)
+ : SecurityQueryPtr(message) {}
// PrioritizedQueue requires this method to decide which priority to assign
size_t PriorityOrder() const {
return 0;
@@ -65,9 +66,8 @@ typedef threads::MessageLoopThread<SecurityMessageQueue> SecurityMessageLoop;
/**
* \brief SecurityManagerImpl class implements SecurityManager interface
*/
-class SecurityManagerImpl
- : public SecurityManager,
- public SecurityMessageLoop::Handler {
+class SecurityManagerImpl : public SecurityManager,
+ public SecurityMessageLoop::Handler {
public:
/**
* \brief Constructor
@@ -78,7 +78,8 @@ class SecurityManagerImpl
* Overriden ProtocolObserver::OnMessageReceived method
* \param message Message with supporting params received
*/
- void OnMessageReceived(const ::protocol_handler::RawMessagePtr message) OVERRIDE;
+ void OnMessageReceived(
+ const ::protocol_handler::RawMessagePtr message) OVERRIDE;
/**
* \brief Post message to Mobile Application
* Empty *overriden ProtocolObserver::OnMessageReceived method
@@ -91,28 +92,29 @@ class SecurityManagerImpl
* \param session_observer pointer to object of the class implementing
*/
void set_session_observer(
- protocol_handler::SessionObserver *observer) OVERRIDE;
+ protocol_handler::SessionObserver* observer) OVERRIDE;
/**
* \brief Sets pointer for Protocol Handler layer for sending
* \param protocol_handler pointer to object of the class implementing
*/
void set_protocol_handler(
- protocol_handler::ProtocolHandler *protocol_handler_) OVERRIDE;
+ protocol_handler::ProtocolHandler* protocol_handler_) OVERRIDE;
/**
* \brief Sets pointer for CryptoManager for handling SSLContext
* \param crypto_manager pointer to object of the class implementing
*/
- void set_crypto_manager(CryptoManager *crypto_manager) OVERRIDE;
+ void set_crypto_manager(CryptoManager* crypto_manager) OVERRIDE;
/**
* \brief Sends InternallError with text message to mobile application
- * \param connection_key Unique key used by other components as session identifier
+ * \param connection_key Unique key used by other components as session
+ * identifier
* \param error_id unique error identifier
* \param erorr_text SSL impelmentation error text
* \param seq_number received from Mobile Application
*/
void SendInternalError(const uint32_t connection_key,
- const uint8_t &error_id,
- const std::string &erorr_text,
+ const uint8_t& error_id,
+ const std::string& erorr_text,
const uint32_t seq_number) OVERRIDE;
using SecurityManager::SendInternalError;
@@ -127,10 +129,11 @@ class SecurityManagerImpl
/**
* \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 identifier
+ * \param connection_key Unique key used by other components as session
+ * 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) OVERRIDE;
/**
* \brief Start handshake as SSL client
@@ -140,50 +143,61 @@ class SecurityManagerImpl
/**
* \brief Add/Remove for SecurityManagerListener
*/
- void AddListener(SecurityManagerListener *const listener) OVERRIDE;
- void RemoveListener(SecurityManagerListener *const listener) OVERRIDE;
+ 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 identifier
+ * \param connection_key Unique key used by other components as session
+ * identifier
* \param success result of connection protection
*/
- void NotifyListenersOnHandshakeDone(const uint32_t &connection_key,
- const bool success);
+ void NotifyListenersOnHandshakeDone(const uint32_t& connection_key,
+ SSLContext::HandshakeResult error);
+
+ /**
+ * @brief Notifiers for listeners.
+ * Allows to notify that certificate should be updated
+ */
+ void NotifyOnCertififcateUpdateRequired();
+
/**
* @brief SecurityConfigSection
* @return Session name in config file
*/
- static const char *ConfigSection();
+ static const char* ConfigSection();
+
private:
/**
* \brief Sends Handshake binary data to mobile application
- * \param connection_key Unique key used by other components as session identifier
+ * \param connection_key Unique key used by other components as session
+ * identifier
* \param data pointer to binary data array
* \param data_size size of binary data array
* \param seq_number received from Mobile Application
*/
void SendHandshakeBinData(const uint32_t connection_key,
- const uint8_t *const data,
+ const uint8_t* const data,
const size_t data_size,
const uint32_t seq_number = 0);
/**
* \brief Parse SecurityMessage as HandshakeData request
* \param inMessage SecurityMessage with binary data of handshake
*/
- bool ProccessHandshakeData(const SecurityMessage &inMessage);
+ bool ProccessHandshakeData(const SecurityMessage& inMessage);
/**
* \brief Parse InternalError from mobile side
* \param inMessage SecurityMessage with binary data of handshake
*/
- bool ProccessInternalError(const SecurityMessage &inMessage);
+ bool ProccessInternalError(const SecurityMessage& inMessage);
/**
* \brief Sends security query
* Create new array as concatenation of header and binary data
* \param query SecurityQuery for sending via Control service
- * \param connection_key Unique key used by other components as session identifier
+ * \param connection_key Unique key used by other components as session
+ * identifier
*/
- void SendQuery(const SecurityQuery &query, const uint32_t connection_key);
+ void SendQuery(const SecurityQuery& query, const uint32_t connection_key);
// Thread that pumps handshake data
SecurityMessageLoop security_messages_;
@@ -191,19 +205,19 @@ class SecurityManagerImpl
/**
*\brief Pointer on instance of class implementing SessionObserver
*/
- protocol_handler::SessionObserver *session_observer_;
+ protocol_handler::SessionObserver* session_observer_;
/**
*\brief Pointer on instance of class implementing CryptoManager
*/
- security_manager::CryptoManager *crypto_manager_;
+ security_manager::CryptoManager* crypto_manager_;
/**
*\brief Pointer on instance of class implementing ProtocolHandler
*/
- protocol_handler::ProtocolHandler *protocol_handler_;
+ protocol_handler::ProtocolHandler* protocol_handler_;
/**
*\brief List of listeners for notify handshake done result
*/
- std::list<SecurityManagerListener *> listeners_;
+ std::list<SecurityManagerListener*> listeners_;
DISALLOW_COPY_AND_ASSIGN(SecurityManagerImpl);
};
} // namespace security_manager
diff --git a/src/components/security_manager/include/security_manager/security_query.h b/src/components/security_manager/include/security_manager/security_query.h
deleted file mode 100644
index c9f0b5843f..0000000000
--- a/src/components/security_manager/include/security_manager/security_query.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef SRC_COMPONENTS_SECURITY_MANAGER_INCLUDE_SECURITY_MANAGER_SECURITY_QUERY_H_
-#define SRC_COMPONENTS_SECURITY_MANAGER_INCLUDE_SECURITY_MANAGER_SECURITY_QUERY_H_
-
-#include <stdint.h>
-#include <cstddef>
-#include <vector>
-#include <string>
-#include "utils/shared_ptr.h"
-
-namespace security_manager {
-/**
- * \brief SecurityQuery is wrapper for handling Mobile messages
- * as security queries
- */
-class SecurityQuery {
- public:
- /**
- * \brief QueryType is 1 byte type of income query
- * Equal RPC Type (Ford Binary Header Definition)
- */
- enum QueryType {
- REQUEST = 0x00,
- RESPONSE = 0x10,
- NOTIFICATION = 0x20,
- INVALID_QUERY_TYPE = 0xFF
- };
- /**
- * \brief QueryId is 3 byte identifier of income query
- * Equal RPC Function ID (Ford Binary Header Definition)
- */
- enum QueryId {
- SEND_HANDSHAKE_DATA = 0x1,
- SEND_INTERNAL_ERROR = 0x2,
- INVALID_QUERY_ID = 0xFFFFFF
- };
- /**
- * \brief QueryHeader is 12 byte header of security query
- * Equal Ford Binary Header Definition
- */
- struct QueryHeader {
- QueryHeader();
- QueryHeader(uint8_t queryType, uint32_t queryId,
- uint32_t seqNumber = 0, uint32_t jsonSize= 0);
- // TODO(EZamakhov): check bitfield correctness on other endianness platform
- uint32_t query_type:8;
- uint32_t query_id:24; // API function identifier
- uint32_t seq_number; // request sequential number
- uint32_t json_size;
- };
-
- /**
- * \brief Constructor
- */
- SecurityQuery();
- /**
- * \brief Constructor with header and connection_key
- * \param connection_key Unique key used by other components as session identifier
- * \param header QueryHeader
- */
- SecurityQuery(const QueryHeader &header, const uint32_t connection_key);
- /**
- * \brief Constructor with header, connection_key and query binary data
- * \param connection_key Unique key used by other components as session identifier
- * \param raw_data pointer to binary data array
- * \param raw_data_size size of binary data array
- * \param header QueryHeader
- */
- SecurityQuery(const QueryHeader &header, const uint32_t connection_key,
- const uint8_t *const raw_data, const size_t raw_data_size);
- /**
- * \brief Serialize income from Mobile Application data
- * as query with header and binary data or json message
- * \param raw_data pointer to binary data array
- * \param raw_data_size size of binary data array
- * \return \c true on correct parse and \c false on wrong size of data
- */
- bool SerializeQuery(const uint8_t *const raw_data, const size_t raw_data_size);
- /**
- * \brief Deserialize query for sending to Mobile Application
- * \return \c vector of uint8_t data (serialized header data and send_data))
- */
- const std::vector<uint8_t> DeserializeQuery() const;
- /**
- * \brief Set binary data. (No header modification)
- * \param binary_data pointer to binary data array
- * \param bin_data_size size of binary data array
- */
- void set_data(const uint8_t *const binary_data, const size_t bin_data_size);
- /**
- * \brief Set json data. (No header modification)
- * \param json_message string with json error
- */
- void set_json_message(const std::string &json_message);
- /**
- * \brief Set connection key
- * \param connection_key Unique key used by other components as session identifier
- */
- void set_connection_key(const uint32_t connection_key);
- /**
- * \brief Set query header
- * \param header of query
- */
- void set_header(const QueryHeader &header);
- /**
- * \brief Get query header
- * \return header of query
- */
- const QueryHeader &get_header() const;
- /**
- * \brief Get query binary data (without header data)
- * \return const pointer to const binary data
- */
- const uint8_t *get_data() const;
- /**
- * \brief Get query binary data size
- * \return size of binary data
- */
- size_t get_data_size() const;
- /**
- * \brief Get json string data (without header data)
- * \return const pointer to const binary data
- */
- const std::string &get_json_message() const;
- /**
- * \brief Get connection key
- * \return Unique key used by other components as session identifier
- */
- uint32_t get_connection_key() const;
-
- private:
- /**
- *\brief 12 byte header of security query
- * Equal Ford Binary Header Definition
- */
- QueryHeader header_;
- /**
- *\brief nique key used by other components as session identifier
- */
- uint32_t connection_key_;
- /**
- *\brief Binary data of query (without header info)
- */
- std::vector<uint8_t> data_;
- /**
- *\brief JSON (string) value of query
- */
- std::string json_message_;
-};
-/**
-*\brief SmartPointer wrapper
-*/
-typedef utils::SharedPtr<SecurityQuery> SecurityQueryPtr;
-} // namespace security_manager
-#endif // SRC_COMPONENTS_SECURITY_MANAGER_INCLUDE_SECURITY_MANAGER_SECURITY_QUERY_H_
diff --git a/src/components/security_manager/src/crypto_manager_impl.cc b/src/components/security_manager/src/crypto_manager_impl.cc
index 69121a7b19..f44198953b 100644
--- a/src/components/security_manager/src/crypto_manager_impl.cc
+++ b/src/components/security_manager/src/crypto_manager_impl.cc
@@ -31,143 +31,205 @@
*/
#include "security_manager/crypto_manager_impl.h"
+
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+
+#include <fstream>
+#include <iostream>
+#include <stdio.h>
+#include <ctime>
#include "security_manager/security_manager.h"
+
#include "utils/logger.h"
#include "utils/atomic.h"
+#include "utils/macro.h"
+#include "utils/scope_guard.h"
+#include "utils/date_time.h"
-#define TLS1_1_MINIMAL_VERSION 0x1000103fL
-#define CONST_SSL_METHOD_MINIMAL_VERSION 0x00909000L
+#define TLS1_1_MINIMAL_VERSION 0x1000103fL
+#define CONST_SSL_METHOD_MINIMAL_VERSION 0x00909000L
namespace security_manager {
-CREATE_LOGGERPTR_GLOBAL(logger_, "CryptoManagerImpl")
+CREATE_LOGGERPTR_GLOBAL(logger_, "SecurityManager")
uint32_t CryptoManagerImpl::instance_count_ = 0;
+sync_primitives::Lock CryptoManagerImpl::instance_lock_;
-CryptoManagerImpl::CryptoManagerImpl()
- : context_(NULL), mode_(CLIENT) {
+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);
+ LOG4CXX_WARN(logger_,
+ "Certificate verification failed with error "
+ << error << " \"" << X509_verify_cert_error_string(error)
+ << '"');
+ }
+ return preverify_ok;
}
-bool CryptoManagerImpl::Init(Mode mode,
- Protocol protocol,
- const std::string &cert_filename,
- const std::string &key_filename,
- const std::string &ciphers_list,
- bool verify_peer) {
- if (atomic_post_inc(&instance_count_) == 0) {
+void free_ctx(SSL_CTX** ctx) {
+ if (ctx) {
+ SSL_CTX_free(*ctx);
+ *ctx = NULL;
+ }
+}
+}
+
+CryptoManagerImpl::CryptoManagerImpl(
+ const utils::SharedPtr<const CryptoManagerSettings> set)
+ : settings_(set), context_(NULL) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(instance_lock_);
+ instance_count_++;
+ if (instance_count_ == 1) {
+ LOG4CXX_DEBUG(logger_, "Openssl engine initialization");
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
SSL_library_init();
}
+}
- mode_ = mode;
+CryptoManagerImpl::~CryptoManagerImpl() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(instance_lock_);
+ LOG4CXX_DEBUG(logger_, "Deinitilization");
+ if (!context_) {
+ LOG4CXX_WARN(logger_, "Manager is not initialized");
+ } else {
+ SSL_CTX_free(context_);
+ }
+ instance_count_--;
+ if (instance_count_ == 0) {
+ LOG4CXX_DEBUG(logger_, "Openssl engine deinitialization");
+ EVP_cleanup();
+ ERR_free_strings();
+ }
+}
+
+bool CryptoManagerImpl::Init() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const Mode mode = get_settings().security_manager_mode();
const bool is_server = (mode == SERVER);
+ if (is_server) {
+ LOG4CXX_DEBUG(logger_, "Server mode");
+ } else {
+ LOG4CXX_DEBUG(logger_, "Client mode");
+ }
+ LOG4CXX_DEBUG(logger_,
+ "Peer verification "
+ << (get_settings().verify_peer() ? "enabled" : "disabled"));
+ LOG4CXX_DEBUG(logger_,
+ "CA certificate file is \"" << get_settings().ca_cert_path()
+ << '"');
+
#if OPENSSL_VERSION_NUMBER < CONST_SSL_METHOD_MINIMAL_VERSION
- SSL_METHOD *method;
+ SSL_METHOD* method;
#else
- const SSL_METHOD *method;
+ const SSL_METHOD* method;
#endif
- switch (protocol) {
+ switch (get_settings().security_manager_protocol_name()) {
case SSLv3:
- method = is_server ?
- SSLv3_server_method() :
- SSLv3_client_method();
+ method = is_server ? SSLv3_server_method() : SSLv3_client_method();
break;
case TLSv1:
- method = is_server ?
- TLSv1_server_method() :
- TLSv1_client_method();
+ method = is_server ? TLSv1_server_method() : TLSv1_client_method();
break;
case TLSv1_1:
#if OPENSSL_VERSION_NUMBER < TLS1_1_MINIMAL_VERSION
- LOG4CXX_WARN(logger_,
- "OpenSSL has no TLSv1.1 with version lower 1.0.1, set TLSv1.0");
- method = is_server ?
- TLSv1_server_method() :
- TLSv1_client_method();
+ LOG4CXX_WARN(
+ logger_,
+ "OpenSSL has no TLSv1.1 with version lower 1.0.1, set TLSv1.0");
+ method = is_server ? TLSv1_server_method() : TLSv1_client_method();
#else
- method = is_server ?
- TLSv1_1_server_method() :
- TLSv1_1_client_method();
+ method = is_server ? TLSv1_1_server_method() : TLSv1_1_client_method();
#endif
break;
case TLSv1_2:
#if OPENSSL_VERSION_NUMBER < TLS1_1_MINIMAL_VERSION
- LOG4CXX_WARN(logger_,
- "OpenSSL has no TLSv1.2 with version lower 1.0.1, set TLSv1.0");
- method = is_server ?
- TLSv1_server_method() :
- TLSv1_client_method();
+ LOG4CXX_WARN(
+ logger_,
+ "OpenSSL has no TLSv1.2 with version lower 1.0.1, set TLSv1.0");
+ method = is_server ? TLSv1_server_method() : TLSv1_client_method();
#else
- method = is_server ?
- TLSv1_2_server_method() :
- TLSv1_2_client_method();
+ method = is_server ? TLSv1_2_server_method() : TLSv1_2_client_method();
#endif
break;
default:
- LOG4CXX_ERROR(logger_, "Unknown protocol: " << protocol);
+ LOG4CXX_ERROR(logger_,
+ "Unknown protocol: "
+ << get_settings().security_manager_protocol_name());
return false;
}
+ if (context_) {
+ free_ctx(&context_);
+ }
context_ = SSL_CTX_new(method);
+ utils::ScopeGuard guard = utils::MakeGuard(free_ctx, &context_);
+
// Disable SSL2 as deprecated
SSL_CTX_set_options(context_, SSL_OP_NO_SSLv2);
- if (cert_filename.empty()) {
- LOG4CXX_WARN(logger_, "Empty certificate path");
+ set_certificate(get_settings().certificate_data());
+
+ if (get_settings().ciphers_list().empty()) {
+ LOG4CXX_WARN(logger_, "Empty ciphers list");
} else {
- LOG4CXX_INFO(logger_, "Certificate path: " << cert_filename);
- if (!SSL_CTX_use_certificate_file(context_, cert_filename.c_str(),
- SSL_FILETYPE_PEM)) {
- LOG4CXX_ERROR(logger_, "Could not use certificate " << cert_filename);
+ LOG4CXX_DEBUG(logger_, "Cipher list: " << get_settings().ciphers_list());
+ if (!SSL_CTX_set_cipher_list(context_,
+ get_settings().ciphers_list().c_str())) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Could not set cipher list: " << get_settings().ciphers_list());
return false;
}
}
- if (key_filename.empty()) {
- LOG4CXX_WARN(logger_, "Empty key path");
- } else {
- LOG4CXX_INFO(logger_, "Key path: " << key_filename);
- if (!SSL_CTX_use_PrivateKey_file(context_, key_filename.c_str(),
- SSL_FILETYPE_PEM)) {
- LOG4CXX_ERROR(logger_, "Could not use key " << key_filename);
- return false;
- }
- if (!SSL_CTX_check_private_key(context_)) {
- LOG4CXX_ERROR(logger_, "Could not use certificate " << cert_filename);
- return false;
- }
+ if (get_settings().ca_cert_path().empty()) {
+ LOG4CXX_WARN(logger_, "Setting up empty CA certificate location");
}
- if (ciphers_list.empty()) {
- LOG4CXX_WARN(logger_, "Empty ciphers list");
- } else {
- LOG4CXX_INFO(logger_, "Cipher list: " << ciphers_list);
- if (!SSL_CTX_set_cipher_list(context_, ciphers_list.c_str())) {
- LOG4CXX_ERROR(logger_, "Could not set cipher list: " << ciphers_list);
- return false;
- }
+ LOG4CXX_DEBUG(logger_, "Setting up CA certificate location");
+ const int result = SSL_CTX_load_verify_locations(
+ context_, NULL, get_settings().ca_cert_path().c_str());
+
+ if (!result) {
+ const unsigned long error = ERR_get_error();
+ UNUSED(error);
+ LOG4CXX_WARN(logger_,
+ "Wrong certificate file '"
+ << get_settings().ca_cert_path() << "', err 0x" << std::hex
+ << error << " \"" << ERR_reason_error_string(error)
+ << '"');
}
- // TODO(EZamakhov): add loading SSL_VERIFY_FAIL_IF_NO_PEER_CERT from INI
- const int verify_mode = verify_peer
- ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
- : SSL_VERIFY_NONE;
- SSL_CTX_set_verify(context_, verify_mode, NULL);
+ guard.Dismiss();
+ const int verify_mode =
+ get_settings().verify_peer()
+ ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
+ : SSL_VERIFY_NONE;
+ LOG4CXX_DEBUG(logger_,
+ "Setting up peer verification in mode: " << verify_mode);
+ SSL_CTX_set_verify(context_, verify_mode, &debug_callback);
return true;
}
-void CryptoManagerImpl::Finish() {
- SSL_CTX_free(context_);
- if (atomic_post_dec(&instance_count_) == 1) {
- EVP_cleanup();
- ERR_free_strings();
+bool CryptoManagerImpl::OnCertificateUpdated(const std::string& data) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!context_) {
+ LOG4CXX_WARN(logger_, "Not initialized");
+ return false;
}
+
+ return set_certificate(data);
}
SSLContext* CryptoManagerImpl::CreateSSLContext() {
@@ -175,19 +237,21 @@ SSLContext* CryptoManagerImpl::CreateSSLContext() {
return NULL;
}
- SSL *conn = SSL_new(context_);
+ SSL* conn = SSL_new(context_);
if (conn == NULL)
return NULL;
- if (mode_ == SERVER) {
+ if (get_settings().security_manager_mode() == SERVER) {
SSL_set_accept_state(conn);
} else {
SSL_set_connect_state(conn);
}
- return new SSLContextImpl(conn, mode_);
+ return new SSLContextImpl(conn,
+ get_settings().security_manager_mode(),
+ get_settings().maximum_payload_size());
}
-void CryptoManagerImpl::ReleaseSSLContext(SSLContext *context) {
+void CryptoManagerImpl::ReleaseSSLContext(SSLContext* context) {
delete context;
}
@@ -195,8 +259,142 @@ std::string CryptoManagerImpl::LastError() const {
if (!context_) {
return std::string("Initialization is not completed");
}
- const char *reason = ERR_reason_error_string(ERR_get_error());
+ const char* reason = ERR_reason_error_string(ERR_get_error());
return std::string(reason ? reason : "");
}
+bool CryptoManagerImpl::IsCertificateUpdateRequired() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const time_t cert_date = mktime(&expiration_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 expiration time: " << asctime(&expiration_time_));
+ LOG4CXX_DEBUG(logger_,
+ "Host time: " << asctime(localtime(&now))
+ << ". Seconds before expiration: " << seconds);
+ if (seconds < 0) {
+ LOG4CXX_WARN(logger_, "Certificate is already expired.");
+ return true;
+ }
+
+ return seconds <= (get_settings().update_before_hours() *
+ date_time::DateTime::SECONDS_IN_HOUR);
+}
+
+const CryptoManagerSettings& CryptoManagerImpl::get_settings() const {
+ return *settings_;
+}
+
+bool CryptoManagerImpl::set_certificate(const std::string& cert_data) {
+ if (cert_data.empty()) {
+ LOG4CXX_WARN(logger_, "Empty certificate");
+ return false;
+ }
+
+ BIO* bio = BIO_new(BIO_f_base64());
+ BIO* bmem = BIO_new_mem_buf((char*)cert_data.c_str(), cert_data.length());
+ bmem = BIO_push(bio, bmem);
+
+ char* buf = new char[cert_data.length()];
+ int len = BIO_read(bmem, buf, cert_data.length());
+
+ BIO* bio_cert = BIO_new(BIO_s_mem());
+ if (NULL == bio_cert) {
+ LOG4CXX_WARN(logger_, "Unable to update certificate. BIO not created");
+ return false;
+ }
+
+ utils::ScopeGuard bio_guard = utils::MakeGuard(BIO_free, bio_cert);
+ UNUSED(bio_guard)
+ int k = 0;
+ if ((k = BIO_write(bio_cert, buf, len)) <= 0) {
+ LOG4CXX_WARN(logger_, "Unable to write into BIO");
+ return false;
+ }
+
+ PKCS12* p12 = d2i_PKCS12_bio(bio_cert, NULL);
+ if (NULL == p12) {
+ LOG4CXX_ERROR(logger_, "Unable to parse certificate");
+ return false;
+ }
+
+ EVP_PKEY* pkey = NULL;
+ X509* cert = NULL;
+ PKCS12_parse(p12, NULL, &pkey, &cert, NULL);
+
+ if (NULL == cert || NULL == pkey) {
+ LOG4CXX_WARN(logger_, "Either certificate or key not valid.");
+ return false;
+ }
+
+ if (!SSL_CTX_use_certificate(context_, cert)) {
+ LOG4CXX_WARN(logger_, "Could not use certificate");
+ return false;
+ }
+
+ asn1_time_to_tm(X509_get_notAfter(cert));
+
+ if (!SSL_CTX_use_PrivateKey(context_, pkey)) {
+ LOG4CXX_ERROR(logger_, "Could not use key");
+ return false;
+ }
+ if (!SSL_CTX_check_private_key(context_)) {
+ LOG4CXX_ERROR(logger_, "Could not use certificate ");
+ return false;
+ }
+ return true;
+}
+
+int CryptoManagerImpl::pull_number_from_buf(char* buf, int* idx) {
+ if (!idx) {
+ return 0;
+ }
+ const int val = ((buf[*idx] - '0') * 10) + buf[(*idx) + 1] - '0';
+ *idx = *idx + 2;
+ 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;
+ }
+}
+
} // namespace security_manager
diff --git a/src/components/security_manager/src/security_manager_impl.cc b/src/components/security_manager/src/security_manager_impl.cc
index dee1770e70..556cc291d1 100644
--- a/src/components/security_manager/src/security_manager_impl.cc
+++ b/src/components/security_manager/src/security_manager_impl.cc
@@ -45,9 +45,10 @@ static const char* kErrId = "id";
static const char* kErrText = "text";
SecurityManagerImpl::SecurityManagerImpl()
- : security_messages_("SecurityManager", this),
- session_observer_(NULL), crypto_manager_(NULL), protocol_handler_(NULL) {
-}
+ : security_messages_("SecurityManager", this)
+ , session_observer_(NULL)
+ , crypto_manager_(NULL)
+ , protocol_handler_(NULL) {}
void SecurityManagerImpl::OnMessageReceived(
const ::protocol_handler::RawMessagePtr message) {
@@ -56,14 +57,14 @@ void SecurityManagerImpl::OnMessageReceived(
}
SecurityMessage securityMessagePtr(new SecurityQuery());
- const bool result = securityMessagePtr->SerializeQuery(
- message->data(), message->data_size());
+ const bool result =
+ securityMessagePtr->SerializeQuery(message->data(), message->data_size());
if (!result) {
// result will be false only if data less then query header
const std::string error_text("Incorrect message received");
LOG4CXX_ERROR(logger_, error_text);
- SendInternalError(message->connection_key(),
- ERROR_INVALID_QUERY_SIZE, error_text);
+ SendInternalError(
+ message->connection_key(), ERROR_INVALID_QUERY_SIZE, error_text);
return;
}
securityMessagePtr->set_connection_key(message->connection_key());
@@ -73,11 +74,10 @@ void SecurityManagerImpl::OnMessageReceived(
}
void SecurityManagerImpl::OnMobileMessageSent(
- const ::protocol_handler::RawMessagePtr ) {
-}
+ const ::protocol_handler::RawMessagePtr) {}
void SecurityManagerImpl::set_session_observer(
- protocol_handler::SessionObserver *observer) {
+ protocol_handler::SessionObserver* observer) {
if (!observer) {
LOG4CXX_ERROR(logger_, "Invalid (NULL) pointer to SessionObserver.");
return;
@@ -86,7 +86,7 @@ void SecurityManagerImpl::set_session_observer(
}
void SecurityManagerImpl::set_protocol_handler(
- protocol_handler::ProtocolHandler *handler) {
+ protocol_handler::ProtocolHandler* handler) {
if (!handler) {
LOG4CXX_ERROR(logger_, "Invalid (NULL) pointer to ProtocolHandler.");
return;
@@ -94,7 +94,7 @@ void SecurityManagerImpl::set_protocol_handler(
protocol_handler_ = handler;
}
-void SecurityManagerImpl::set_crypto_manager(CryptoManager *crypto_manager) {
+void SecurityManagerImpl::set_crypto_manager(CryptoManager* crypto_manager) {
if (!crypto_manager) {
LOG4CXX_ERROR(logger_, "Invalid (NULL) pointer to CryptoManager.");
return;
@@ -105,11 +105,11 @@ void SecurityManagerImpl::set_crypto_manager(CryptoManager *crypto_manager) {
void SecurityManagerImpl::Handle(const SecurityMessage message) {
DCHECK(message);
LOG4CXX_INFO(logger_, "Received Security message from Mobile side");
- if (!crypto_manager_) {
+ if (!crypto_manager_) {
const std::string error_text("Invalid (NULL) CryptoManager.");
LOG4CXX_ERROR(logger_, error_text);
- SendInternalError(message->get_connection_key(),
- ERROR_NOT_SUPPORTED, error_text);
+ SendInternalError(
+ message->get_connection_key(), ERROR_NOT_SUPPORTED, error_text);
return;
}
switch (message->get_header().query_id) {
@@ -128,21 +128,21 @@ void SecurityManagerImpl::Handle(const SecurityMessage message) {
const std::string error_text("Unknown query identifier.");
LOG4CXX_ERROR(logger_, error_text);
SendInternalError(message->get_connection_key(),
- ERROR_INVALID_QUERY_ID, error_text,
+ ERROR_INVALID_QUERY_ID,
+ error_text,
message->get_header().seq_number);
- }
- break;
- }
+ } break;
+ }
}
-security_manager::SSLContext *SecurityManagerImpl::CreateSSLContext(
- const uint32_t &connection_key) {
+security_manager::SSLContext* SecurityManagerImpl::CreateSSLContext(
+ const uint32_t& connection_key) {
LOG4CXX_INFO(logger_, "ProtectService processing");
DCHECK(session_observer_);
DCHECK(crypto_manager_);
- security_manager::SSLContext *ssl_context =
- session_observer_->GetSSLContext(connection_key, protocol_handler::kControl);
+ 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;
@@ -153,12 +153,12 @@ security_manager::SSLContext *SecurityManagerImpl::CreateSSLContext(
const std::string error_text("CryptoManager could not create SSL context.");
LOG4CXX_ERROR(logger_, error_text);
// Generate response query and post to security_messages_
- SendInternalError(connection_key, ERROR_INTERNAL,
- error_text);
+ SendInternalError(connection_key, ERROR_INTERNAL, error_text);
return NULL;
}
- const int result = session_observer_->SetSSLContext(connection_key, ssl_context);
+ const int result =
+ session_observer_->SetSSLContext(connection_key, ssl_context);
if (ERROR_SUCCESS != result) {
// delete SSLContext on any error
crypto_manager_->ReleaseSSLContext(ssl_context);
@@ -167,38 +167,51 @@ security_manager::SSLContext *SecurityManagerImpl::CreateSSLContext(
}
DCHECK(session_observer_->GetSSLContext(connection_key,
protocol_handler::kControl));
- LOG4CXX_DEBUG(logger_, "Set SSL context to connection_key " << connection_key);
+ LOG4CXX_DEBUG(logger_,
+ "Set SSL context to connection_key " << connection_key);
return ssl_context;
}
void SecurityManagerImpl::StartHandshake(uint32_t connection_key) {
DCHECK(session_observer_);
LOG4CXX_INFO(logger_, "StartHandshake: connection_key " << connection_key);
- security_manager::SSLContext *ssl_context =
- session_observer_->GetSSLContext(connection_key,
- protocol_handler::kControl);
+ security_manager::SSLContext* ssl_context = session_observer_->GetSSLContext(
+ connection_key, protocol_handler::kControl);
if (!ssl_context) {
- const std::string error_text("StartHandshake failed, "
- "connection is not protected");
+ const std::string error_text(
+ "StartHandshake failed, "
+ "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 (crypto_manager_->IsCertificateUpdateRequired()) {
+ NotifyOnCertififcateUpdateRequired();
+ }
+
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 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
@@ -206,26 +219,29 @@ void SecurityManagerImpl::StartHandshake(uint32_t connection_key) {
SendHandshakeBinData(connection_key, data, data_size);
}
}
-void SecurityManagerImpl::AddListener(SecurityManagerListener *const listener) {
+void SecurityManagerImpl::AddListener(SecurityManagerListener* const listener) {
if (!listener) {
- LOG4CXX_ERROR(logger_, "Invalid (NULL) pointer to SecurityManagerListener.");
+ LOG4CXX_ERROR(logger_,
+ "Invalid (NULL) pointer to SecurityManagerListener.");
return;
}
listeners_.push_back(listener);
}
-void SecurityManagerImpl::RemoveListener(SecurityManagerListener *const listener) {
+void SecurityManagerImpl::RemoveListener(
+ SecurityManagerListener* const listener) {
if (!listener) {
- LOG4CXX_ERROR(logger_, "Invalid (NULL) pointer to SecurityManagerListener.");
+ LOG4CXX_ERROR(logger_,
+ "Invalid (NULL) pointer to SecurityManagerListener.");
return;
}
listeners_.remove(listener);
}
-void SecurityManagerImpl::NotifyListenersOnHandshakeDone(const uint32_t &connection_key,
- const bool success) {
- LOG4CXX_TRACE(logger_, "NotifyListenersOnHandshakeDone");
+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 {
@@ -234,140 +250,166 @@ void SecurityManagerImpl::NotifyListenersOnHandshakeDone(const uint32_t &connect
}
}
-bool SecurityManagerImpl::ProccessHandshakeData(const SecurityMessage &inMessage) {
+void SecurityManagerImpl::NotifyOnCertififcateUpdateRequired() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ std::list<SecurityManagerListener*>::iterator it = listeners_.begin();
+ while (it != listeners_.end()) {
+ (*it)->OnCertificateUpdateRequired();
+ ++it;
+ }
+}
+
+bool SecurityManagerImpl::ProccessHandshakeData(
+ const SecurityMessage& inMessage) {
LOG4CXX_INFO(logger_, "SendHandshakeData processing");
DCHECK(inMessage);
- DCHECK(inMessage->get_header().query_id == SecurityQuery::SEND_HANDSHAKE_DATA);
+ DCHECK(inMessage->get_header().query_id ==
+ SecurityQuery::SEND_HANDSHAKE_DATA);
const uint32_t seqNumber = inMessage->get_header().seq_number;
const uint32_t connection_key = inMessage->get_connection_key();
- LOG4CXX_DEBUG(logger_, "Received " << inMessage->get_data_size()
- << " bytes handshake data ");
+ LOG4CXX_DEBUG(logger_,
+ "Received " << inMessage->get_data_size()
+ << " bytes handshake data ");
if (!inMessage->get_data_size()) {
const std::string error_text("SendHandshakeData: null arguments size.");
LOG4CXX_ERROR(logger_, error_text);
- SendInternalError(connection_key, ERROR_INVALID_QUERY_SIZE,
- error_text, seqNumber);
+ SendInternalError(
+ connection_key, ERROR_INVALID_QUERY_SIZE, error_text, seqNumber);
return false;
}
DCHECK(session_observer_);
- SSLContext *sslContext =
- session_observer_->GetSSLContext(connection_key,
- protocol_handler::kControl);
+ SSLContext* sslContext = session_observer_->GetSSLContext(
+ connection_key, protocol_handler::kControl);
if (!sslContext) {
const std::string error_text("SendHandshakeData: No ssl context.");
LOG4CXX_ERROR(logger_, error_text);
- SendInternalError(connection_key, ERROR_SERVICE_NOT_PROTECTED,
- error_text, seqNumber);
- NotifyListenersOnHandshakeDone(connection_key, false);
+ SendInternalError(
+ connection_key, ERROR_SERVICE_NOT_PROTECTED, error_text, seqNumber);
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Fail);
return false;
}
size_t out_data_size;
- const uint8_t *out_data;
+ const uint8_t* out_data;
const SSLContext::HandshakeResult handshake_result =
- sslContext->DoHandshakeStep(inMessage->get_data(), inMessage->get_data_size(),
- &out_data, &out_data_size);
+ sslContext->DoHandshakeStep(inMessage->get_data(),
+ inMessage->get_data_size(),
+ &out_data,
+ &out_data_size);
if (handshake_result == SSLContext::Handshake_Result_AbnormalFail) {
// Do not return handshake data on AbnormalFail or null returned values
const std::string erorr_text(sslContext->LastError());
- LOG4CXX_ERROR(logger_, "SendHandshakeData: Handshake failed: " << erorr_text);
- SendInternalError(connection_key,
- ERROR_SSL_INVALID_DATA, erorr_text, seqNumber);
- NotifyListenersOnHandshakeDone(connection_key, false);
+ LOG4CXX_ERROR(logger_,
+ "SendHandshakeData: Handshake failed: " << erorr_text);
+ SendInternalError(
+ connection_key, ERROR_SSL_INVALID_DATA, erorr_text, seqNumber);
+ 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);
- } else if (handshake_result == SSLContext::Handshake_Result_Fail) {
+ NotifyListenersOnHandshakeDone(connection_key,
+ SSLContext::Handshake_Result_Success);
+ } else if (handshake_result != SSLContext::Handshake_Result_Success) {
// On handshake fail
LOG4CXX_WARN(logger_, "SSL initialization finished with fail.");
- NotifyListenersOnHandshakeDone(connection_key, false);
+ NotifyListenersOnHandshakeDone(connection_key, handshake_result);
}
if (out_data && out_data_size) {
// answer with the same seqNumber as income message
- SendHandshakeBinData(connection_key, out_data, out_data_size,
- seqNumber);
+ SendHandshakeBinData(connection_key, out_data, out_data_size, seqNumber);
}
return true;
}
-bool SecurityManagerImpl::ProccessInternalError(const SecurityMessage &inMessage) {
- LOG4CXX_INFO(logger_, "Received InternalError with Json message"
- << inMessage->get_json_message());
+bool SecurityManagerImpl::ProccessInternalError(
+ const SecurityMessage& inMessage) {
+ LOG4CXX_INFO(logger_,
+ "Received InternalError with Json message"
+ << inMessage->get_json_message());
Json::Value root;
Json::Reader reader;
const bool parsingSuccessful =
reader.parse(inMessage->get_json_message(), root);
if (!parsingSuccessful)
return false;
- LOG4CXX_DEBUG(logger_, "Received InternalError id " << root[kErrId].asString()
- << ", text: " << root[kErrText].asString());
+ LOG4CXX_DEBUG(logger_,
+ "Received InternalError id "
+ << root[kErrId].asString()
+ << ", text: " << root[kErrText].asString());
return true;
}
-void SecurityManagerImpl::SendHandshakeBinData(
- const uint32_t connection_key, const uint8_t *const data,
- const size_t data_size, const uint32_t seq_number) {
- const SecurityQuery::QueryHeader header(
- SecurityQuery::NOTIFICATION,
- SecurityQuery::SEND_HANDSHAKE_DATA, seq_number);
- DCHECK(data_size < 1024 * 1024 *1024 );
- const SecurityQuery query = SecurityQuery(header, connection_key, data, data_size);
+void SecurityManagerImpl::SendHandshakeBinData(const uint32_t connection_key,
+ const uint8_t* const data,
+ const size_t data_size,
+ const uint32_t seq_number) {
+ const SecurityQuery::QueryHeader header(SecurityQuery::NOTIFICATION,
+ SecurityQuery::SEND_HANDSHAKE_DATA,
+ seq_number);
+ DCHECK(data_size < 1024 * 1024 * 1024);
+ const SecurityQuery query =
+ SecurityQuery(header, connection_key, data, data_size);
SendQuery(query, connection_key);
LOG4CXX_DEBUG(logger_, "Sent " << data_size << " bytes handshake data ");
}
void SecurityManagerImpl::SendInternalError(const uint32_t connection_key,
- const uint8_t &error_id,
- const std::string &erorr_text,
- const uint32_t seq_number) {
+ const uint8_t& error_id,
+ const std::string& erorr_text,
+ const uint32_t seq_number) {
Json::Value value;
- value[kErrId] = error_id;
+ value[kErrId] = error_id;
value[kErrText] = erorr_text;
const std::string error_str = value.toStyledString();
- SecurityQuery::QueryHeader header(SecurityQuery::NOTIFICATION,
- SecurityQuery::SEND_INTERNAL_ERROR,
- // header save json size only (exclude last byte)
- seq_number, error_str.size());
+ SecurityQuery::QueryHeader header(
+ SecurityQuery::NOTIFICATION,
+ SecurityQuery::SEND_INTERNAL_ERROR,
+ // header save json size only (exclude last byte)
+ seq_number,
+ error_str.size());
// Raw data is json string and error id at last byte
std::vector<uint8_t> data_sending(error_str.size() + 1);
memcpy(&data_sending[0], error_str.c_str(), error_str.size());
- data_sending[data_sending.size()-1] = error_id;
+ data_sending[data_sending.size() - 1] = error_id;
- const SecurityQuery query(header, connection_key,
- &data_sending[0], data_sending.size());
+ const SecurityQuery query(
+ header, connection_key, &data_sending[0], data_sending.size());
SendQuery(query, connection_key);
- LOG4CXX_DEBUG(logger_, "Sent Internal error id " << static_cast<int>(error_id)
- << " : \"" << erorr_text << "\".");
+ LOG4CXX_DEBUG(logger_,
+ "Sent Internal error id " << static_cast<int>(error_id)
+ << " : \"" << erorr_text << "\".");
}
void SecurityManagerImpl::SendQuery(const SecurityQuery& query,
- const uint32_t connection_key) {
+ const uint32_t connection_key) {
const std::vector<uint8_t> data_sending = query.DeserializeQuery();
uint32_t connection_handle = 0;
uint8_t sessionID = 0;
uint8_t protocol_version;
- session_observer_->PairFromKey(connection_key, &connection_handle,
- &sessionID);
- if (session_observer_->ProtocolVersionUsed(connection_handle, sessionID,
- protocol_version)) {
+ session_observer_->PairFromKey(
+ connection_key, &connection_handle, &sessionID);
+ if (session_observer_->ProtocolVersionUsed(
+ connection_handle, sessionID, protocol_version)) {
const ::protocol_handler::RawMessagePtr rawMessagePtr(
- new protocol_handler::RawMessage(connection_key,
- protocol_version,
- &data_sending[0], data_sending.size(),
- protocol_handler::kControl));
+ new protocol_handler::RawMessage(connection_key,
+ protocol_version,
+ &data_sending[0],
+ data_sending.size(),
+ protocol_handler::kControl));
DCHECK(protocol_handler_);
// Add RawMessage to ProtocolHandler message query
protocol_handler_->SendMessageToMobileApp(rawMessagePtr, false);
}
}
-const char *SecurityManagerImpl::ConfigSection() {
+const char* SecurityManagerImpl::ConfigSection() {
return "Security Manager";
}
diff --git a/src/components/security_manager/src/security_query.cc b/src/components/security_manager/src/security_query.cc
index cd4da03c15..60233dde5e 100644
--- a/src/components/security_manager/src/security_query.cc
+++ b/src/components/security_manager/src/security_query.cc
@@ -38,35 +38,37 @@
namespace security_manager {
SecurityQuery::QueryHeader::QueryHeader()
- : query_type(INVALID_QUERY_TYPE), query_id(INVALID_QUERY_ID),
- seq_number(0), json_size(0) {
-}
-
-SecurityQuery::QueryHeader::QueryHeader(uint8_t queryType, uint32_t queryId,
- uint32_t seqNumber, uint32_t jsonSize)
- : query_type(queryType), query_id(queryId),
- seq_number(seqNumber), json_size(jsonSize) {
-}
+ : query_type(INVALID_QUERY_TYPE)
+ , query_id(INVALID_QUERY_ID)
+ , seq_number(0)
+ , json_size(0) {}
+
+SecurityQuery::QueryHeader::QueryHeader(uint8_t queryType,
+ uint32_t queryId,
+ uint32_t seqNumber,
+ uint32_t jsonSize)
+ : query_type(queryType)
+ , query_id(queryId)
+ , seq_number(seqNumber)
+ , json_size(jsonSize) {}
SecurityQuery::SecurityQuery()
- : header_(INVALID_QUERY_TYPE, INVALID_QUERY_ID, 0), connection_key_(0) {
-}
+ : header_(INVALID_QUERY_TYPE, INVALID_QUERY_ID, 0), connection_key_(0) {}
-SecurityQuery::SecurityQuery(const SecurityQuery::QueryHeader &header,
+SecurityQuery::SecurityQuery(const SecurityQuery::QueryHeader& header,
const uint32_t connection_key,
- const uint8_t *const raw_data,
+ const uint8_t* const raw_data,
const size_t raw_data_size)
- : header_(header), connection_key_(connection_key),
- data_(raw_data, raw_data + raw_data_size) {
-}
+ : header_(header)
+ , connection_key_(connection_key)
+ , data_(raw_data, raw_data + raw_data_size) {}
-SecurityQuery::SecurityQuery(const SecurityQuery::QueryHeader &header,
+SecurityQuery::SecurityQuery(const SecurityQuery::QueryHeader& header,
const uint32_t connection_key)
- : header_(header), connection_key_(connection_key) {
-}
+ : header_(header), connection_key_(connection_key) {}
-bool SecurityQuery::SerializeQuery(const uint8_t *const raw_data,
- const size_t raw_data_size) {
+bool SecurityQuery::SerializeQuery(const uint8_t* const raw_data,
+ const size_t raw_data_size) {
const size_t header_size = sizeof(QueryHeader);
if (raw_data_size < header_size || !raw_data) {
return false;
@@ -74,21 +76,21 @@ bool SecurityQuery::SerializeQuery(const uint8_t *const raw_data,
const uint8_t query_type = raw_data[0];
switch (query_type) {
case REQUEST:
- header_.query_type = REQUEST;
+ header_.query_type = REQUEST;
break;
case RESPONSE:
- header_.query_type = RESPONSE;
+ header_.query_type = RESPONSE;
break;
case NOTIFICATION:
- header_.query_type = NOTIFICATION;
+ header_.query_type = NOTIFICATION;
break;
default:
header_.query_type = INVALID_QUERY_TYPE;
break;
}
// Convert to Little-Endian and clean high byte
- const uint32_t query_id = 0x00FFFFFF &
- BE_TO_LE32(*reinterpret_cast<const uint32_t*>(raw_data));
+ const uint32_t query_id =
+ 0x00FFFFFF & BE_TO_LE32(*reinterpret_cast<const uint32_t*>(raw_data));
switch (query_id) {
case SEND_HANDSHAKE_DATA:
header_.query_id = SEND_HANDSHAKE_DATA;
@@ -100,22 +102,25 @@ bool SecurityQuery::SerializeQuery(const uint8_t *const raw_data,
header_.query_id = INVALID_QUERY_ID;
break;
}
- header_.seq_number = BE_TO_LE32(*reinterpret_cast<const uint32_t*>(raw_data + 4));
- header_.json_size = BE_TO_LE32(*reinterpret_cast<const uint32_t*>(raw_data + 8));
+ header_.seq_number =
+ BE_TO_LE32(*reinterpret_cast<const uint32_t*>(raw_data + 4));
+ header_.json_size =
+ BE_TO_LE32(*reinterpret_cast<const uint32_t*>(raw_data + 8));
if (header_.json_size > raw_data_size - header_size)
return false;
if (header_.json_size > 0) {
- const char *const json_data =
+ const char* const json_data =
reinterpret_cast<const char*>(raw_data + header_size);
json_message_.assign(json_data, json_data + header_.json_size);
}
- const uint32_t bin_data_size = raw_data_size - (header_size + header_.json_size);
+ const uint32_t bin_data_size =
+ raw_data_size - (header_size + header_.json_size);
if (bin_data_size > 0) {
- const char *const bin_data =
- reinterpret_cast<const char*>(raw_data + header_size + header_.json_size);
+ const char* const bin_data = reinterpret_cast<const char*>(
+ raw_data + header_size + header_.json_size);
data_.assign(bin_data, bin_data + bin_data_size);
}
return true;
@@ -124,31 +129,33 @@ bool SecurityQuery::SerializeQuery(const uint8_t *const raw_data,
const std::vector<uint8_t> SecurityQuery::DeserializeQuery() const {
SecurityQuery::QueryHeader deserialize_header(header_);
const uint32_t tmp = deserialize_header.query_id << 8;
- deserialize_header.query_id = LE_TO_BE32(tmp);
+ deserialize_header.query_id = LE_TO_BE32(tmp);
deserialize_header.seq_number = LE_TO_BE32(deserialize_header.seq_number);
- deserialize_header.json_size = LE_TO_BE32(deserialize_header.json_size);
+ deserialize_header.json_size = LE_TO_BE32(deserialize_header.json_size);
const size_t header_size = sizeof(deserialize_header);
// vector of header and raw_data
- std::vector<uint8_t> data_sending(header_size + data_.size() + json_message_.size());
+ std::vector<uint8_t> data_sending(header_size + data_.size() +
+ json_message_.size());
// copy header
memcpy(&data_sending[0], &deserialize_header, header_size);
// copy binary data
std::copy(data_.begin(), data_.end(), data_sending.begin() + header_size);
// copy text (json) data
- std::copy(json_message_.begin(), json_message_.end(),
+ std::copy(json_message_.begin(),
+ json_message_.end(),
data_sending.begin() + header_size + data_.size());
return data_sending;
}
-void SecurityQuery::set_data(const uint8_t *const binary_data,
- const size_t bin_data_size) {
- DCHECK(binary_data);
- DCHECK(bin_data_size);
- data_.assign(binary_data, binary_data + bin_data_size);
+void SecurityQuery::set_data(const uint8_t* const binary_data,
+ const size_t bin_data_size) {
+ DCHECK(binary_data);
+ DCHECK(bin_data_size);
+ data_.assign(binary_data, binary_data + bin_data_size);
}
-void SecurityQuery::set_json_message(const std::string &json_message) {
+void SecurityQuery::set_json_message(const std::string& json_message) {
json_message_ = json_message;
}
@@ -156,11 +163,11 @@ void SecurityQuery::set_connection_key(const uint32_t connection_key) {
connection_key_ = connection_key;
}
-void SecurityQuery::set_header(const SecurityQuery::QueryHeader &header) {
+void SecurityQuery::set_header(const SecurityQuery::QueryHeader& header) {
header_ = header;
}
-const SecurityQuery::QueryHeader &SecurityQuery::get_header() const {
+const SecurityQuery::QueryHeader& SecurityQuery::get_header() const {
return header_;
}
@@ -172,7 +179,7 @@ size_t SecurityQuery::get_data_size() const {
return data_.size();
}
-const std::string &SecurityQuery::get_json_message() const {
+const std::string& SecurityQuery::get_json_message() const {
return json_message_;
}
diff --git a/src/components/security_manager/src/ssl_context_impl.cc b/src/components/security_manager/src/ssl_context_impl.cc
index 09c2efd196..6f53234867 100644
--- a/src/components/security_manager/src/ssl_context_impl.cc
+++ b/src/components/security_manager/src/ssl_context_impl.cc
@@ -37,22 +37,25 @@
#include <openssl/err.h>
#include <memory.h>
#include <map>
+#include <algorithm>
#include "utils/macro.h"
namespace security_manager {
-CryptoManagerImpl::SSLContextImpl::SSLContextImpl(SSL *conn, Mode mode)
- : connection_(conn),
- bioIn_(BIO_new(BIO_s_mem())),
- bioOut_(BIO_new(BIO_s_mem())),
- bioFilter_(NULL),
- // TODO(EZamakhov): get MTU by parameter (from transport)
- // default buffer size is TCP MTU
- buffer_size_(1500),
- buffer_(new uint8_t[buffer_size_]),
- is_handshake_pending_(false),
- mode_(mode) {
+CREATE_LOGGERPTR_GLOBAL(logger_, "SecurityManager")
+
+CryptoManagerImpl::SSLContextImpl::SSLContextImpl(SSL* conn,
+ Mode mode,
+ size_t maximum_payload_size)
+ : connection_(conn)
+ , bioIn_(BIO_new(BIO_s_mem()))
+ , bioOut_(BIO_new(BIO_s_mem()))
+ , bioFilter_(NULL)
+ , buffer_size_(maximum_payload_size)
+ , buffer_(new uint8_t[buffer_size_])
+ , is_handshake_pending_(false)
+ , mode_(mode) {
SSL_set_bio(connection_, bioIn_, bioOut_);
}
@@ -60,7 +63,7 @@ std::string CryptoManagerImpl::SSLContextImpl::LastError() const {
if (!IsInitCompleted()) {
return std::string("Initialization is not completed");
}
- const char *reason = ERR_reason_error_string(ERR_get_error());
+ const char* reason = ERR_reason_error_string(ERR_get_error());
return std::string(reason ? reason : "");
}
@@ -69,137 +72,273 @@ bool CryptoManagerImpl::SSLContextImpl::IsInitCompleted() const {
return SSL_is_init_finished(connection_);
}
-SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::
-StartHandshake(const uint8_t** const out_data, size_t *out_data_size) {
+SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::StartHandshake(
+ const uint8_t** const out_data, size_t* out_data_size) {
is_handshake_pending_ = true;
return DoHandshakeStep(NULL, 0, out_data, out_data_size);
}
namespace {
- size_t aes128_gcm_sha256_max_block_size(size_t mtu) {
- if (mtu < 29)
- return 0;
- return mtu - 29;
- }
- size_t rc4_md5_max_block_size(size_t mtu) {
- if (mtu < 21)
- return 0;
- return mtu - 21;
- }
- size_t rc4_sha_max_block_size(size_t mtu) {
- if (mtu < 25)
- return 0;
- return mtu - 25;
- }
- size_t seed_sha_max_block_size(size_t mtu) {
- if (mtu < 53)
- return 0;
- return ((mtu - 37) & 0xfffffff0) - 5;
- }
- size_t aes128_sha256_max_block_size(size_t mtu) {
- if (mtu < 69)
- return 0;
- return ((mtu - 53) & 0xfffffff0) - 1;
- }
- size_t des_cbc3_sha_max_block_size(size_t mtu) {
- if (mtu < 37)
- return 0;
- return ((mtu - 29) & 0xfffffff8) - 5;
- }
+size_t aes128_gcm_sha256_max_block_size(size_t mtu) {
+ if (mtu < 29)
+ return 0;
+ return mtu - 29;
+}
+size_t rc4_md5_max_block_size(size_t mtu) {
+ if (mtu < 21)
+ return 0;
+ return mtu - 21;
+}
+size_t rc4_sha_max_block_size(size_t mtu) {
+ if (mtu < 25)
+ return 0;
+ return mtu - 25;
+}
+size_t seed_sha_max_block_size(size_t mtu) {
+ if (mtu < 53)
+ return 0;
+ return ((mtu - 37) & 0xfffffff0) - 5;
+}
+size_t aes128_sha256_max_block_size(size_t mtu) {
+ if (mtu < 69)
+ return 0;
+ return ((mtu - 53) & 0xfffffff0) - 1;
+}
+size_t des_cbc3_sha_max_block_size(size_t mtu) {
+ if (mtu < 37)
+ return 0;
+ return ((mtu - 29) & 0xfffffff8) - 5;
+}
} // namespace
std::map<std::string, CryptoManagerImpl::SSLContextImpl::BlockSizeGetter>
CryptoManagerImpl::SSLContextImpl::create_max_block_sizes() {
std::map<std::string, CryptoManagerImpl::SSLContextImpl::BlockSizeGetter> rc;
- rc.insert(std::make_pair("AES128-GCM-SHA256", aes128_gcm_sha256_max_block_size));
- rc.insert(std::make_pair("AES128-SHA256", aes128_sha256_max_block_size));
- rc.insert(std::make_pair("AES128-SHA", seed_sha_max_block_size));
- rc.insert(std::make_pair("AES256-GCM-SHA384", aes128_gcm_sha256_max_block_size));
- rc.insert(std::make_pair("AES256-SHA256", aes128_sha256_max_block_size));
- rc.insert(std::make_pair("AES256-SHA", seed_sha_max_block_size));
- rc.insert(std::make_pair("CAMELLIA128-SHA", seed_sha_max_block_size));
- rc.insert(std::make_pair("CAMELLIA256-SHA", seed_sha_max_block_size));
- rc.insert(std::make_pair("DES-CBC3-SHA", des_cbc3_sha_max_block_size));
- rc.insert(std::make_pair("DES-CBC-SHA", des_cbc3_sha_max_block_size));
- rc.insert(std::make_pair("RC4-MD5", rc4_md5_max_block_size));
- rc.insert(std::make_pair("RC4-SHA", rc4_sha_max_block_size));
- rc.insert(std::make_pair("SEED-SHA", seed_sha_max_block_size));
+ rc.insert(
+ std::make_pair("AES128-GCM-SHA256", aes128_gcm_sha256_max_block_size));
+ rc.insert(std::make_pair("AES128-SHA256", aes128_sha256_max_block_size));
+ rc.insert(std::make_pair("AES128-SHA", seed_sha_max_block_size));
+ rc.insert(
+ std::make_pair("AES256-GCM-SHA384", aes128_gcm_sha256_max_block_size));
+ rc.insert(std::make_pair("AES256-SHA256", aes128_sha256_max_block_size));
+ rc.insert(std::make_pair("AES256-SHA", seed_sha_max_block_size));
+ rc.insert(std::make_pair("CAMELLIA128-SHA", seed_sha_max_block_size));
+ rc.insert(std::make_pair("CAMELLIA256-SHA", seed_sha_max_block_size));
+ rc.insert(std::make_pair("DES-CBC3-SHA", des_cbc3_sha_max_block_size));
+ rc.insert(std::make_pair("DES-CBC-SHA", des_cbc3_sha_max_block_size));
+ rc.insert(std::make_pair("RC4-MD5", rc4_md5_max_block_size));
+ rc.insert(std::make_pair("RC4-SHA", rc4_sha_max_block_size));
+ rc.insert(std::make_pair("SEED-SHA", seed_sha_max_block_size));
return rc;
}
std::map<std::string, CryptoManagerImpl::SSLContextImpl::BlockSizeGetter>
-CryptoManagerImpl::SSLContextImpl::max_block_sizes =
- CryptoManagerImpl::SSLContextImpl::create_max_block_sizes();
+ CryptoManagerImpl::SSLContextImpl::max_block_sizes =
+ CryptoManagerImpl::SSLContextImpl::create_max_block_sizes();
+
+void CryptoManagerImpl::SSLContextImpl::PrintCertData(
+ X509* cert, const std::string& cert_owner) {
+ if (cert) {
+ 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_, cert_owner << " 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_, cert_owner << " issuer:" << issuer);
+ OPENSSL_free(issuer);
+ }
-SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::
-DoHandshakeStep(const uint8_t* const in_data, size_t in_data_size,
- const uint8_t** const out_data, size_t* out_data_size) {
- DCHECK(out_data);
- 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;
+ ASN1_TIME* notBefore = X509_get_notBefore(cert);
+ ASN1_TIME* notAfter = X509_get_notAfter(cert);
+
+ if (notBefore) {
+ LOG4CXX_DEBUG(logger_, " Start date: " << (char*)notBefore->data);
+ }
+ if (notAfter) {
+ LOG4CXX_DEBUG(logger_, " End date: " << (char*)notAfter->data);
+ }
}
+}
+
+void CryptoManagerImpl::SSLContextImpl::PrintCertInfo() {
+ PrintCertData(SSL_get_certificate(connection_), "HU's");
+
+ 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);
+ PrintCertData(cert, "SERVERS");
+ }
+}
+
+SSLContext::HandshakeResult
+CryptoManagerImpl::SSLContextImpl::CheckCertContext() {
+ 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;
+ }
+
+ X509_NAME* subj_name = X509_get_subject_name(cert);
+
+ const std::string& cn = GetTextBy(subj_name, NID_commonName);
+ const std::string& sn = GetTextBy(subj_name, NID_serialNumber);
+
+ if (!(hsh_context_.expected_cn.CompareIgnoreCase(cn.c_str()))) {
+ LOG4CXX_ERROR(logger_,
+ "Trying to run handshake with wrong app name: "
+ << cn << ". Expected app name: "
+ << hsh_context_.expected_cn.AsMBString());
+ return Handshake_Result_AppNameMismatch;
+ }
+
+ if (!(hsh_context_.expected_sn.CompareIgnoreCase(sn.c_str()))) {
+ LOG4CXX_ERROR(logger_,
+ "Trying to run handshake with wrong app id: "
+ << sn << ". Expected app id: "
+ << hsh_context_.expected_sn.AsMBString());
+ return Handshake_Result_AppIDMismatch;
+ }
+ return Handshake_Result_Success;
+}
+
+bool CryptoManagerImpl::SSLContextImpl::ReadHandshakeData(
+ const uint8_t** const out_data, size_t* out_data_size) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const size_t pend = BIO_ctrl_pending(bioOut_);
+ LOG4CXX_DEBUG(logger_, "Available " << pend << " bytes for handshake");
+
+ if (pend > 0) {
+ LOG4CXX_DEBUG(logger_, "Reading handshake data");
+ EnsureBufferSizeEnough(pend);
+
+ const int read_count = BIO_read(bioOut_, buffer_, pend);
+ if (read_count == static_cast<int>(pend)) {
+ *out_data_size = read_count;
+ *out_data = buffer_;
+ } else {
+ LOG4CXX_WARN(logger_, "BIO read fail");
+ is_handshake_pending_ = false;
+ ResetConnection();
+ return false;
+ }
+ }
+
+ return true;
+}
+bool CryptoManagerImpl::SSLContextImpl::WriteHandshakeData(
+ const uint8_t* const in_data, size_t in_data_size) {
+ LOG4CXX_AUTO_TRACE(logger_);
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;
}
}
+ return true;
+}
+SSLContext::HandshakeResult
+CryptoManagerImpl::SSLContextImpl::PerformHandshake() {
const int handshake_result = SSL_do_handshake(connection_);
if (handshake_result == 1) {
+ const HandshakeResult result = CheckCertContext();
+ if (result != Handshake_Result_Success) {
+ ResetConnection();
+ is_handshake_pending_ = false;
+ return result;
+ }
+
+ LOG4CXX_DEBUG(logger_, "SSL handshake successfully finished");
// Handshake is successful
bioFilter_ = BIO_new(BIO_f_ssl());
BIO_set_ssl(bioFilter_, connection_, BIO_NOCLOSE);
- const SSL_CIPHER *cipher = SSL_get_current_cipher(connection_);
+ const SSL_CIPHER* cipher = SSL_get_current_cipher(connection_);
max_block_size_ = max_block_sizes[SSL_CIPHER_get_name(cipher)];
is_handshake_pending_ = false;
+
} 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);
+ }
}
+ return Handshake_Result_Success;
+}
- const size_t pend = BIO_ctrl_pending(bioOut_);
+SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::DoHandshakeStep(
+ const uint8_t* const in_data,
+ size_t in_data_size,
+ const uint8_t** const out_data,
+ size_t* out_data_size) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(out_data);
+ DCHECK(out_data_size);
+ *out_data = NULL;
+ *out_data_size = 0;
- if (pend) {
- EnsureBufferSizeEnough(pend);
+ // TODO(Ezamakhov): add test - hanshake fail -> restart StartHandshake
+ {
+ sync_primitives::AutoLock locker(bio_locker);
- const int read_count = BIO_read(bioOut_, buffer_, pend);
- if (read_count == static_cast<int>(pend)) {
- *out_data_size = read_count;
- *out_data = buffer_;
- } else {
+ if (SSL_is_init_finished(connection_)) {
+ LOG4CXX_DEBUG(logger_, "SSL initilization is finished");
is_handshake_pending_ = false;
- SSL_clear(connection_);
- return SSLContext::Handshake_Result_AbnormalFail;
+ return Handshake_Result_Success;
}
}
- return SSLContext::Handshake_Result_Success;
-}
+ if (!WriteHandshakeData(in_data, in_data_size)) {
+ return Handshake_Result_AbnormalFail;
+ }
-bool CryptoManagerImpl::SSLContextImpl::Encrypt(
- const uint8_t * const in_data, size_t in_data_size,
- const uint8_t ** const out_data, size_t *out_data_size) {
+ PrintCertInfo();
+ const HandshakeResult res = PerformHandshake();
+ if (res != Handshake_Result_Success) {
+ return res;
+ }
+
+ if (!ReadHandshakeData(out_data, out_data_size)) {
+ return Handshake_Result_AbnormalFail;
+ }
+
+ return res;
+}
+
+bool CryptoManagerImpl::SSLContextImpl::Encrypt(const uint8_t* const in_data,
+ size_t in_data_size,
+ const uint8_t** const out_data,
+ size_t* out_data_size) {
sync_primitives::AutoLock locker(bio_locker);
- if (!SSL_is_init_finished(connection_) ||
- !in_data ||
- !in_data_size) {
+ if (!SSL_is_init_finished(connection_) || !in_data || !in_data_size) {
return false;
}
@@ -220,10 +359,10 @@ bool CryptoManagerImpl::SSLContextImpl::Encrypt(
return true;
}
-bool CryptoManagerImpl::SSLContextImpl::Decrypt(
- const uint8_t * const in_data, size_t in_data_size,
- const uint8_t ** const out_data, size_t *out_data_size) {
-
+bool CryptoManagerImpl::SSLContextImpl::Decrypt(const uint8_t* const in_data,
+ size_t in_data_size,
+ const uint8_t** const out_data,
+ size_t* out_data_size) {
sync_primitives::AutoLock locker(bio_locker);
if (!SSL_is_init_finished(connection_)) {
return false;
@@ -274,14 +413,94 @@ 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_;
- buffer_ = new(std::nothrow) uint8_t[size];
+ buffer_ = new (std::nothrow) uint8_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) {
+ LOG4CXX_WARN(logger_,
+ "Unable to obtain object: " << object << " from certificate");
+ return std::string();
+ }
+
+ std::vector<char> data;
+ data.resize(req_len + 1);
+ X509_NAME_get_text_by_NID(name, object, &data.front(), data.size());
+
+ std::string str(data.begin(), data.end() - 1);
+
+ std::transform(str.begin(), str.end(), str.begin(), ::tolower);
+ return str;
+}
+
} // namespace security_manager
diff --git a/src/components/security_manager/test/CMakeLists.txt b/src/components/security_manager/test/CMakeLists.txt
index 6554bb797f..6707e5ea5a 100644
--- a/src/components/security_manager/test/CMakeLists.txt
+++ b/src/components/security_manager/test/CMakeLists.txt
@@ -35,14 +35,17 @@ include_directories(
${COMPONENTS_DIR}/protocol_handler/test/include
${COMPONENTS_DIR}/transport_manager/test/include
${COMPONENTS_DIR}/security_manager/include
- include
+ ${COMPONENTS_DIR}/resumption/include
+ ${JSONCPP_INCLUDE_DIRECTORY}
)
set(SOURCES
- #${COMPONENTS_DIR}/security_manager/test/crypto_manager_impl_test.cc
- #${COMPONENTS_DIR}/security_manager/test/security_manager_test.cc
- #${COMPONENTS_DIR}/security_manager/test/security_query_test.cc
+ ${COMPONENTS_DIR}/security_manager/test/crypto_manager_impl_test.cc
+ ${COMPONENTS_DIR}/security_manager/test/security_manager_test.cc
+ ${COMPONENTS_DIR}/security_manager/test/security_query_test.cc
${COMPONENTS_DIR}/security_manager/test/security_query_matcher.cc
+ ${COMPONENTS_DIR}/security_manager/test/ssl_context_test.cc
+ ${COMPONENTS_DIR}/security_manager/test/ssl_certificate_handshake_test.cc
)
set(LIBRARIES
@@ -55,12 +58,17 @@ set(CERT_LIST
${CMAKE_SOURCE_DIR}/mykey.pem
)
+add_custom_target(generate_certificates
+ COMMAND ${CMAKE_SOURCE_DIR}/tools/Utils/generate_test_certificates.py
+ -d=${CMAKE_CURRENT_BINARY_DIR} -s
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+)
+
foreach( file_i ${CERT_LIST})
file(COPY ${file_i} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
endforeach( file_i )
-add_library (test_security_manager ${SOURCES})
-target_link_libraries (test_security_manager ${LIBRARIES} )
create_test (security_manager_test "${SOURCES}" "${LIBRARIES}")
+add_dependencies(security_manager_test generate_certificates)
endif ()
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 52ac42b418..27f91866ac 100644
--- a/src/components/security_manager/test/crypto_manager_impl_test.cc
+++ b/src/components/security_manager/test/crypto_manager_impl_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Ford Motor Company
+ * Copyright (c) 2016, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,433 +30,239 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <gtest/gtest.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "security_manager/crypto_manager.h"
-#include "security_manager/crypto_manager_impl.h"
-#include "security_manager/ssl_context.h"
-
#ifdef __QNXNTO__
#include <openssl/ssl3.h>
#else
-#include <openssl/tls1.h>
-#endif
+#include <openssl/ssl.h>
+#endif //__QNXNTO__
+#include <limits>
+#include <fstream>
+#include <sstream>
+
+#include "gtest/gtest.h"
+#include "security_manager/crypto_manager_impl.h"
+#include "security_manager/mock_security_manager_settings.h"
+
+using ::testing::Return;
+using ::testing::ReturnRef;
+using ::testing::NiceMock;
+
+namespace {
+const size_t kUpdatesBeforeHour = 24;
+const std::string kAllCiphers = "ALL";
+const std::string kCaCertPath = "";
#ifdef __QNXNTO__
-#define FORD_CIPHER SSL3_TXT_RSA_DES_192_CBC3_SHA
+const std::string kFordCipher = SSL3_TXT_RSA_DES_192_CBC3_SHA;
#else
// Used cipher from ford protocol requirement
-#define FORD_CIPHER TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384
+const std::string kFordCipher = TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384;
#endif
-
-#define ALL_CIPHERS "ALL"
+}
namespace test {
namespace components {
-namespace security_manager_test {
+namespace crypto_manager_test {
-namespace {
-bool isErrorFatal(SSL *connection, int res) {
- const int error = SSL_get_error(connection, res);
- return (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_WRITE);
-}
-}
-// TODO(EZamakhov): May be split to SSLContext and Cryptomanager tests (separate files)
-// TODO(EZamakhov): add test for EnsureBufferSizeEnough
-class SSLTest : public testing::Test {
+class CryptoManagerTest : public testing::Test {
protected:
static void SetUpTestCase() {
- crypto_manager = new security_manager::CryptoManagerImpl();
- const bool crypto_manager_initialization = crypto_manager->Init(
- security_manager::SERVER, security_manager::TLSv1_2, "mycert.pem",
- "mykey.pem", FORD_CIPHER, false);
- EXPECT_TRUE(crypto_manager_initialization);
-
- client_manager = new security_manager::CryptoManagerImpl();
- const bool client_manager_initialization = client_manager->Init(
- security_manager::CLIENT, security_manager::TLSv1_2, "", "",
- FORD_CIPHER,
- false);
- EXPECT_TRUE(client_manager_initialization);
+ std::ifstream certificate_file("server/spt_credential.p12.enc");
+ ASSERT_TRUE(certificate_file.is_open())
+ << "Could not open certificate data file";
+
+ const std::string certificate(
+ (std::istreambuf_iterator<char>(certificate_file)),
+ std::istreambuf_iterator<char>());
+ ASSERT_FALSE(certificate.empty()) << "Certificate data file is empty";
+ certificate_data_base64_ = certificate;
}
- static void TearDownTestCase() {
- crypto_manager->Finish();
- client_manager->Finish();
- delete crypto_manager;
- delete client_manager;
+ void SetUp() OVERRIDE {
+ ASSERT_FALSE(certificate_data_base64_.empty());
+ mock_security_manager_settings_ =
+ new NiceMock<security_manager_test::MockCryptoManagerSettings>();
+ utils::SharedPtr<security_manager::CryptoManagerSettings> scrypto =
+ utils::SharedPtr<security_manager::CryptoManagerSettings>::
+ static_pointer_cast<security_manager::CryptoManagerSettings>(
+ mock_security_manager_settings_);
+ crypto_manager_ = new security_manager::CryptoManagerImpl(scrypto);
}
- virtual void SetUp() {
- server_ctx = crypto_manager->CreateSSLContext();
- client_ctx = client_manager->CreateSSLContext();
+ void TearDown() OVERRIDE {
+ delete mock_security_manager_settings_;
+ testing::Mock::AsyncVerifyAndClearExpectations(1000);
}
- virtual void TearDown() {
- crypto_manager->ReleaseSSLContext(server_ctx);
- client_manager->ReleaseSSLContext(client_ctx);
+ void InitSecurityManager() {
+ SetInitialValues(
+ security_manager::CLIENT, security_manager::TLSv1_2, kAllCiphers);
+ const bool crypto_manager_initialization = crypto_manager_->Init();
+ ASSERT_TRUE(crypto_manager_initialization);
}
- static security_manager::CryptoManager* crypto_manager;
- static security_manager::CryptoManager* client_manager;
- security_manager::SSLContext *server_ctx;
- security_manager::SSLContext *client_ctx;
-};
+ void SetInitialValues(security_manager::Mode mode,
+ security_manager::Protocol protocol,
+ const std::string& cipher) {
+ ON_CALL(*mock_security_manager_settings_, security_manager_mode())
+ .WillByDefault(Return(mode));
+ ON_CALL(*mock_security_manager_settings_, security_manager_protocol_name())
+ .WillByDefault(Return(protocol));
+ ON_CALL(*mock_security_manager_settings_, certificate_data())
+ .WillByDefault(ReturnRef(certificate_data_base64_));
+ ON_CALL(*mock_security_manager_settings_, ciphers_list())
+ .WillByDefault(ReturnRef(cipher));
+ ON_CALL(*mock_security_manager_settings_, ca_cert_path())
+ .WillByDefault(ReturnRef(kCaCertPath));
+ ON_CALL(*mock_security_manager_settings_, verify_peer())
+ .WillByDefault(Return(false));
+ }
+
+ security_manager::CryptoManager* crypto_manager_;
+ static std::string certificate_data_base64_;
-security_manager::CryptoManager* SSLTest::crypto_manager;
-security_manager::CryptoManager* SSLTest::client_manager;
+ NiceMock<security_manager_test::MockCryptoManagerSettings>*
+ mock_security_manager_settings_;
+};
+std::string CryptoManagerTest::certificate_data_base64_;
-TEST(CryptoManagerTest, UsingBeforeInit) {
- security_manager::CryptoManager *crypto_manager = new security_manager::CryptoManagerImpl();
- EXPECT_TRUE(crypto_manager->CreateSSLContext() == NULL);
- EXPECT_EQ(crypto_manager->LastError(), std::string ("Initialization is not completed"));
- delete crypto_manager;
+TEST_F(CryptoManagerTest, UsingBeforeInit) {
+ EXPECT_TRUE(crypto_manager_->CreateSSLContext() == NULL);
+ EXPECT_EQ(std::string("Initialization is not completed"),
+ crypto_manager_->LastError());
}
-TEST(CryptoManagerTest, WrongInit) {
- security_manager::CryptoManager *crypto_manager = new security_manager::CryptoManagerImpl();
+TEST_F(CryptoManagerTest, WrongInit) {
+ // We have to cast (-1) to security_manager::Protocol Enum to be accepted by
+ // crypto_manager_->Init(...)
+ // Unknown protocol version
+ security_manager::Protocol UNKNOWN =
+ static_cast<security_manager::Protocol>(-1);
- //We have to cast (-1) to security_manager::Protocol Enum to be accepted by crypto_manager->Init(...)
- security_manager::Protocol UNKNOWN = static_cast<security_manager::Protocol>(-1);
+ EXPECT_CALL(*mock_security_manager_settings_, security_manager_mode())
+ .WillRepeatedly(Return(security_manager::SERVER));
+ EXPECT_CALL(*mock_security_manager_settings_,
+ security_manager_protocol_name()).WillOnce(Return(UNKNOWN));
+ EXPECT_FALSE(crypto_manager_->Init());
- // Unknown protocol version
- EXPECT_FALSE(crypto_manager->Init(security_manager::SERVER, UNKNOWN,
- "mycert.pem", "mykey.pem", FORD_CIPHER, false));
-
- EXPECT_FALSE(crypto_manager->LastError().empty());
- // Unexistent cert file
- EXPECT_FALSE(crypto_manager->Init(security_manager::SERVER, security_manager::TLSv1_2,
- "unexists_file.pem", "mykey.pem", FORD_CIPHER, false));
- EXPECT_FALSE(crypto_manager->LastError().empty());
- // Unexistent key file
- EXPECT_FALSE(crypto_manager->Init(security_manager::SERVER, security_manager::TLSv1_2,
- "mycert.pem", "unexists_file.pem", FORD_CIPHER, false));
- EXPECT_FALSE(crypto_manager->LastError().empty());
+ EXPECT_NE(std::string(), crypto_manager_->LastError());
// Unexistent cipher value
- EXPECT_FALSE(crypto_manager->Init(security_manager::SERVER, security_manager::TLSv1_2,
- "mycert.pem", "mykey.pem", "INVALID_UNKNOWN_CIPHER", false));
- EXPECT_FALSE(crypto_manager->LastError().empty());
+ const std::string invalid_cipher = "INVALID_UNKNOWN_CIPHER";
+ EXPECT_CALL(*mock_security_manager_settings_,
+ security_manager_protocol_name())
+ .WillOnce(Return(security_manager::TLSv1_2));
+ EXPECT_CALL(*mock_security_manager_settings_, certificate_data())
+ .WillOnce(ReturnRef(certificate_data_base64_));
+ EXPECT_CALL(*mock_security_manager_settings_, ciphers_list())
+ .WillRepeatedly(ReturnRef(invalid_cipher));
+ EXPECT_FALSE(crypto_manager_->Init());
+
+ EXPECT_NE(std::string(), crypto_manager_->LastError());
+}
- delete crypto_manager;
+// #ifndef __QNXNTO__
+TEST_F(CryptoManagerTest, CorrectInit) {
+ // Empty cert and key values for SERVER
+ SetInitialValues(
+ security_manager::SERVER, security_manager::TLSv1_2, kFordCipher);
+ EXPECT_TRUE(crypto_manager_->Init());
+
+ // Recall init
+ SetInitialValues(
+ security_manager::CLIENT, security_manager::TLSv1_2, kFordCipher);
+ EXPECT_TRUE(crypto_manager_->Init());
+
+ // Recall init with other protocols
+ SetInitialValues(
+ security_manager::CLIENT, security_manager::TLSv1_2, kFordCipher);
+ EXPECT_TRUE(crypto_manager_->Init());
+
+ SetInitialValues(
+ security_manager::CLIENT, security_manager::TLSv1_1, kFordCipher);
+ EXPECT_TRUE(crypto_manager_->Init());
+
+ // Cipher value
+ SetInitialValues(
+ security_manager::SERVER, security_manager::TLSv1_2, kAllCiphers);
+ EXPECT_TRUE(crypto_manager_->Init());
}
+// #endif // __QNX__
-//TEST(CryptoManagerTest, CorrectInit) {
-// security_manager::CryptoManager *crypto_manager = new security_manager::CryptoManagerImpl();
-// // Empty cert and key values for SERVER
-// EXPECT_TRUE(crypto_manager->Init(security_manager::SERVER, security_manager::TLSv1_2,
-// "", "", FORD_CIPHER, false));
-// EXPECT_TRUE(crypto_manager->LastError().empty());
-// // Recall init
-// EXPECT_TRUE(crypto_manager->Init(security_manager::CLIENT, security_manager::TLSv1_2,
-// "", "", FORD_CIPHER, false));
-// EXPECT_TRUE(crypto_manager->LastError().empty());
-// // Recall init with other protocols
-// EXPECT_TRUE(crypto_manager->Init(security_manager::CLIENT, security_manager::TLSv1_1,
-// "", "", FORD_CIPHER, false));
-// EXPECT_TRUE(crypto_manager->LastError().empty());
-// EXPECT_TRUE(crypto_manager->Init(security_manager::CLIENT, security_manager::TLSv1,
-// "", "", FORD_CIPHER, false));
-// EXPECT_TRUE(crypto_manager->LastError().empty());
-
-// // Cipher value
-// EXPECT_TRUE(crypto_manager->Init(security_manager::SERVER, security_manager::TLSv1_2,
-// "mycert.pem", "mykey.pem", ALL_CIPHERS, false));
-// EXPECT_TRUE(crypto_manager->LastError().empty());
-// delete crypto_manager;
-//}
-
-TEST(CryptoManagerTest, ReleaseNull) {
- using security_manager::CryptoManager;
- using security_manager::CryptoManagerImpl;
-
- CryptoManager *cm = new CryptoManagerImpl();
- EXPECT_NO_THROW(cm->ReleaseSSLContext(NULL));
- delete cm;
+TEST_F(CryptoManagerTest, ReleaseSSLContext_Null) {
+ EXPECT_NO_THROW(crypto_manager_->ReleaseSSLContext(NULL));
}
-TEST_F(SSLTest, BrokenHandshake) {
- const uint8_t *server_buf;
- const uint8_t *client_buf;
- size_t server_buf_len;
- size_t client_buf_len;
- ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
- client_ctx->StartHandshake(&client_buf,
- &client_buf_len));
- ASSERT_FALSE(client_buf == NULL);
- ASSERT_GT(client_buf_len, 0u);
- // Broke 3 bytes for get abnormal fail of handshake
- const_cast<uint8_t*>(client_buf)[0] ^= 0xFF;
- const_cast<uint8_t*>(client_buf)[client_buf_len / 2] ^= 0xFF;
- const_cast<uint8_t*>(client_buf)[client_buf_len - 1] ^= 0xFF;
- ASSERT_EQ(security_manager::SSLContext::Handshake_Result_AbnormalFail,
- server_ctx->DoHandshakeStep(client_buf,
- client_buf_len,
- &server_buf,
- &server_buf_len));
+TEST_F(CryptoManagerTest, CreateReleaseSSLContext) {
+ const size_t max_payload_size = 1000u;
+ SetInitialValues(
+ security_manager::CLIENT, security_manager::TLSv1_2, kAllCiphers);
+ EXPECT_TRUE(crypto_manager_->Init());
+ EXPECT_CALL(*mock_security_manager_settings_, security_manager_mode())
+ .Times(2)
+ .WillRepeatedly(Return(security_manager::CLIENT));
+ EXPECT_CALL(*mock_security_manager_settings_, maximum_payload_size())
+ .Times(1)
+ .WillRepeatedly(Return(max_payload_size));
+
+ security_manager::SSLContext* context = crypto_manager_->CreateSSLContext();
+ EXPECT_TRUE(context);
+ EXPECT_NO_THROW(crypto_manager_->ReleaseSSLContext(context));
}
-// TODO(EZamakhov): split to SSL/TLS1/1.1/1.2 tests
-// TODO{ALeshin}: APPLINK-10846
-//TEST_F(SSLTest, Positive) {
-
-// const uint8_t *server_buf;
-// const uint8_t *client_buf;
-// size_t server_buf_len;
-// size_t client_buf_len;
-// ASSERT_EQ(client_ctx->StartHandshake(&client_buf,
-// &client_buf_len),
-// security_manager::SSLContext::Handshake_Result_Success);
-// ASSERT_FALSE(client_buf == NULL);
-// ASSERT_GT(client_buf_len, 0u);
-
-// for (;;) {
-// ASSERT_EQ(server_ctx->DoHandshakeStep(client_buf,
-// client_buf_len,
-// &server_buf,
-// &server_buf_len),
-// security_manager::SSLContext::Handshake_Result_Success);
-// ASSERT_FALSE(server_buf == NULL);
-// ASSERT_GT(server_buf_len, 0u);
-
-// ASSERT_EQ(client_ctx->DoHandshakeStep(server_buf,
-// server_buf_len,
-// &client_buf,
-// &client_buf_len),
-// security_manager::SSLContext::Handshake_Result_Success);
-// if (server_ctx->IsInitCompleted()) {
-// break;
-// }
-
-// ASSERT_FALSE(client_buf == NULL);
-// ASSERT_GT(client_buf_len, 0u);
-// }
-// // expect empty buffers after init complete
-// ASSERT_TRUE(client_buf == NULL);
-// ASSERT_EQ(client_buf_len, 0u);
-// // expect both side initialization complete
-// EXPECT_TRUE(client_ctx->IsInitCompleted());
-// EXPECT_TRUE(server_ctx->IsInitCompleted());
-
-// // Encrypt text on client side
-// const uint8_t *text = reinterpret_cast<const uint8_t*>("abra");
-// const uint8_t *encrypted_text = 0;
-// size_t text_len = 4;
-// size_t encrypted_text_len;
-// EXPECT_TRUE(client_ctx->Encrypt(text, text_len, &encrypted_text, &encrypted_text_len));
-
-// ASSERT_NE(encrypted_text, (void*)NULL);
-// ASSERT_GT(encrypted_text_len, 0u);
-
-// // Decrypt text on server side
-// EXPECT_TRUE(server_ctx->Decrypt(encrypted_text, encrypted_text_len, &text, &text_len));
-// ASSERT_NE(text, (void*)NULL);
-// ASSERT_GT(text_len, 0u);
-
-// ASSERT_EQ(strncmp(reinterpret_cast<const char*>(text),
-// "abra",
-// 4), 0);
-//}
-
-//TODO{Aleshin}: APPLINK-10846
-//TEST_F(SSLTest, EcncryptionFail) {
-
-// const uint8_t *server_buf;
-// const uint8_t *client_buf;
-// size_t server_buf_len;
-// size_t client_buf_len;
-// ASSERT_EQ(client_ctx->StartHandshake(&client_buf,
-// &client_buf_len),
-// security_manager::SSLContext::Handshake_Result_Success);
-
-// while (!server_ctx->IsInitCompleted()) {
-// ASSERT_FALSE(client_buf == NULL);
-// ASSERT_GT(client_buf_len, 0u);
-// ASSERT_EQ(server_ctx->DoHandshakeStep(client_buf, client_buf_len,
-// &server_buf, &server_buf_len),
-// security_manager::SSLContext::Handshake_Result_Success);
-// ASSERT_FALSE(server_buf == NULL);
-// ASSERT_GT(server_buf_len, 0u);
-
-// ASSERT_EQ(client_ctx->DoHandshakeStep(server_buf, server_buf_len,
-// &client_buf, &client_buf_len),
-// security_manager::SSLContext::Handshake_Result_Success);
-// }
-// // expect empty buffers after init complete
-// ASSERT_TRUE(client_buf == NULL);
-// ASSERT_EQ(client_buf_len, 0u);
-// // expect both side initialization complete
-// EXPECT_TRUE(client_ctx->IsInitCompleted());
-// EXPECT_TRUE(server_ctx->IsInitCompleted());
-
-// // Encrypt text on client side
-// const uint8_t *text = reinterpret_cast<const uint8_t*>("abra");
-// const uint8_t *encrypted_text = 0;
-// size_t text_len = 4;
-// size_t encrypted_text_len;
-// EXPECT_TRUE(client_ctx->Encrypt(text, text_len, &encrypted_text, &encrypted_text_len));
-// ASSERT_NE(encrypted_text, (void*)NULL);
-// ASSERT_GT(encrypted_text_len, 0u);
-
-// std::vector<uint8_t> broken(encrypted_text, encrypted_text + encrypted_text_len);
-// // Broke message
-// broken[encrypted_text_len / 2] ^= 0xFF;
-
-// const uint8_t *out_text;
-// size_t out_text_size;
-// // Decrypt broken text on server side
-// EXPECT_FALSE(server_ctx->Decrypt(&broken[0], broken.size(), &out_text, &out_text_size));
-
-// // Check after broken message that server encryption and decryption fail
-// // Encrypte message on server side
-// EXPECT_FALSE(server_ctx->Decrypt(encrypted_text, encrypted_text_len, &out_text, &out_text_size));
-// EXPECT_FALSE(server_ctx->Encrypt(text, text_len, &encrypted_text, &encrypted_text_len));
-//}
+TEST_F(CryptoManagerTest, OnCertificateUpdated) {
+ InitSecurityManager();
+ EXPECT_TRUE(crypto_manager_->OnCertificateUpdated(certificate_data_base64_));
+}
-/*
- TEST_F(SSLTest, DISABLED_BadData) {
- using security_manager::LastError;
- int res = 0;
-
- uint8_t *outBuf = new uint8_t[1024 * 1024];
- const uint8_t *inBuf;
-
- for(;;) {
- res = SSL_do_handshake(connection);
- if (res >= 0) {
- break;
- }
-
- if (isErrorFatal(connection, res)) {
- break;
- }
-
- size_t outLen = BIO_ctrl_pending(bioOut);
- if (outLen) {
- BIO_read(bioOut, outBuf, outLen);
- }
- size_t inLen;
- server_ctx->DoHandshakeStep(outBuf, outLen, &inBuf, &inLen);
- EXPECT_TRUE(inBuf != NULL);
-
- if (inLen) {
- BIO_write(bioIn, inBuf, inLen);
- }
- }
- delete[] outBuf;
-
- EXPECT_EQ(res, 1);
-
- BIO *bioF = BIO_new(BIO_f_ssl());
- BIO_set_ssl(bioF, connection, BIO_NOCLOSE);
-
- const char *text = "Hello, it's the text to be encrypted";
- uint8_t *encryptedText = new uint8_t[1024];
- const uint8_t *decryptedText;
- size_t text_len;
-
- // Encrypt text on client side
- BIO_write(bioF, text, sizeof(text));
- text_len = BIO_ctrl_pending(bioOut);
- size_t len = BIO_read(bioOut, encryptedText, text_len);
-
- // Make improvements
- encryptedText[len / 3] ^= 0x80;
-
- // Decrypt text on server
- server_ctx->Decrypt(encryptedText, len, &decryptedText, &text_len);
-
- delete[] encryptedText;
-
- EXPECT_FALSE(decryptedText == NULL);
- EXPECT_GT(LastError().length(), 0u);
- delete[] encryptedText;
- }
-
-
-
- TEST_F(SSLTest, Positive2) {
- using security_manager::LastError;
- int res = 0;
-
- uint8_t *outBuf = new uint8_t[1024 * 1024];
- const uint8_t *inBuf;
-
- for(;;) {
- res = SSL_do_handshake(connection);
- if (res >= 0) {
- break;
- }
-
- if (isErrorFatal(connection, res)) {
- break;
- }
-
- size_t outLen = BIO_ctrl_pending(bioOut);
- if (outLen) {
- BIO_read(bioOut, outBuf, outLen);
- }
- size_t inLen;
- server_ctx->DoHandshakeStep(outBuf, outLen, &inBuf, &inLen);
- EXPECT_TRUE(inBuf != NULL);
-
- if (inLen) {
- BIO_write(bioIn, inBuf, inLen);
- }
- }
- delete[] outBuf;
-
- EXPECT_EQ(res, 1);
-
- EXPECT_NE(SSL_is_init_finished(connection), 0u);
-
- BIO *bioF = BIO_new(BIO_f_ssl());
- BIO_set_ssl(bioF, connection, BIO_NOCLOSE);
-
- const int N =1000;
- int last_max = 0;
- int min_oh = N , max_oh = 0;
- for (int l = 1; l < N; ++l) {
- char *text = new char[l+1];
- text[l]='\0';
- uint8_t *encryptedText = new uint8_t[1024*N];
- const uint8_t *decryptedText;
- size_t text_len;
- // Encrypt text on client side
- BIO_write(bioF, text, l);
- text_len = BIO_ctrl_pending(bioOut);
- size_t len = BIO_read(bioOut, encryptedText, text_len);
- const int temp = len - l;
- min_oh = temp < min_oh ? temp : min_oh;
- max_oh = temp > max_oh ? temp : max_oh;
- if (last_max < len) {
- std::cout << l << "->" << len;
- if (l > 1) {
- std::cout << ", last overhead = " << last_max << "-" << l-1
- << " = " << last_max - (l - 1) << "bytes || ";
- std::cout << " overhead = " << len << "-" << l
- << " = " << len - l << "bytes";
- }
- std::cout << std::endl;
- last_max = len;
-
- // Decrypt text on server
- server_ctx->Decrypt(encryptedText, len, &decryptedText, &text_len);
- const_cast<uint8_t*>(decryptedText)[text_len] = 0;
-
- EXPECT_TRUE(decryptedText != NULL);
- EXPECT_EQ(strcmp(reinterpret_cast<const char*>(decryptedText), text), 0u);
- delete[] text;
- }
- std::cout << " min = " << min_oh << ", max = " << max_oh << std::endl;
- }
- //*/
+TEST_F(CryptoManagerTest, OnCertificateUpdated_UpdateNotRequired) {
+ size_t updates_before = 0;
+ SetInitialValues(
+ security_manager::CLIENT, security_manager::TLSv1_2, kAllCiphers);
+ ASSERT_TRUE(crypto_manager_->Init());
+
+ EXPECT_CALL(*mock_security_manager_settings_, update_before_hours())
+ .WillOnce(Return(updates_before));
+
+ EXPECT_FALSE(crypto_manager_->IsCertificateUpdateRequired());
+ size_t max_updates_ = std::numeric_limits<size_t>::max();
+ SetInitialValues(
+ security_manager::CLIENT, security_manager::TLSv1_2, kAllCiphers);
+ EXPECT_CALL(*mock_security_manager_settings_, update_before_hours())
+ .WillOnce(Return(max_updates_));
+ ASSERT_TRUE(crypto_manager_->Init());
+
+ EXPECT_TRUE(crypto_manager_->IsCertificateUpdateRequired());
}
- // namespace crypto_manager_test
-} // namespace components
-} // namespace test
+TEST_F(CryptoManagerTest, OnCertificateUpdated_NotInitialized) {
+ EXPECT_FALSE(crypto_manager_->OnCertificateUpdated(certificate_data_base64_));
+}
+
+TEST_F(CryptoManagerTest, OnCertificateUpdated_NullString) {
+ InitSecurityManager();
+ EXPECT_FALSE(crypto_manager_->OnCertificateUpdated(std::string()));
+}
+
+TEST_F(CryptoManagerTest, OnCertificateUpdated_MalformedSign) {
+ InitSecurityManager();
+ // Corrupt the middle symbol
+ certificate_data_base64_[certificate_data_base64_.size() / 2] = '?';
+
+ EXPECT_FALSE(crypto_manager_->OnCertificateUpdated(certificate_data_base64_));
+}
+
+TEST_F(CryptoManagerTest, OnCertificateUpdated_WrongInitFolder) {
+ SetInitialValues(
+ security_manager::CLIENT, security_manager::TLSv1_2, kAllCiphers);
+ ASSERT_TRUE(crypto_manager_->Init());
+
+ const std::string certificate = "wrong_data";
+ ASSERT_FALSE(certificate.empty());
+
+ EXPECT_FALSE(crypto_manager_->OnCertificateUpdated(certificate));
+}
+
+} // namespace crypto_manager_test
+} // namespace components
+} // namespace test
diff --git a/src/components/security_manager/test/include/security_manager_mock.h b/src/components/security_manager/test/include/security_manager_mock.h
deleted file mode 100644
index 886b022c37..0000000000
--- a/src/components/security_manager/test/include/security_manager_mock.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef TEST_COMPONENTS_SECURITY_MANAGER_INCLUDE_SECURITY_MANAGER_SECURITY_MANAGER_MOCK_H_
-#define TEST_COMPONENTS_SECURITY_MANAGER_INCLUDE_SECURITY_MANAGER_SECURITY_MANAGER_MOCK_H_
-
-#include <gmock/gmock.h>
-#include <string>
-#include <list>
-#include "utils/byte_order.h"
-#include "security_manager/security_manager.h"
-#include "security_manager/ssl_context.h"
-#include "security_manager/security_query.h"
-
-namespace test {
-namespace components {
-namespace security_manager_test {
-
-/*
- * MOCK implementation of ::security_manager::SecurityManager
- */
-class SecurityManagerMock : public ::security_manager::SecurityManager {
- public:
- MOCK_METHOD1(set_session_observer,
- void(::protocol_handler::SessionObserver *));
- MOCK_METHOD1(set_protocol_handler,
- void(::protocol_handler::ProtocolHandler *));
- MOCK_METHOD1(set_crypto_manager,
- void(::security_manager::CryptoManager *));
- 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_METHOD1(StartHandshake,
- void(uint32_t));
- MOCK_METHOD1(AddListener,
- void(::security_manager::SecurityManagerListener *));
- MOCK_METHOD1(RemoveListener,
- void(::security_manager::SecurityManagerListener *));
- // protocol_handler::ProtocolObserver part
- MOCK_METHOD1(OnMessageReceived,
- void(const ::protocol_handler::RawMessagePtr));
- MOCK_METHOD1(OnMobileMessageSent,
- void(const ::protocol_handler::RawMessagePtr));
-};
-
-/*
- * MOCK implementation of protocol_handler::SessionObserver interface
- */
-class SessionObserverMock : public protocol_handler::SessionObserver {
- public:
- MOCK_METHOD2(SetSSLContext,
- int (const uint32_t& key,
- security_manager::SSLContext* context));
- MOCK_METHOD2(GetSSLContext,
- security_manager::SSLContext* (
- const uint32_t& key,
- const protocol_handler::ServiceType& service_type));
- MOCK_METHOD2(SetProtectionFlag,
- void(
- const uint32_t& key,
- const protocol_handler::ServiceType& service_type));
- MOCK_METHOD5(OnSessionStartedCallback,
-
- uint32_t(
- const transport_manager::ConnectionUID &connection_handle,
- const uint8_t session_id,
- const ::protocol_handler::ServiceType &service_type,
- const bool is_protected, uint32_t* hash_id));
-
- MOCK_METHOD4(OnSessionEndedCallback,
- uint32_t(
- const transport_manager::ConnectionUID& connection_handle,
- const uint8_t sessionId,
- const uint32_t& hashCode,
- const protocol_handler::ServiceType& service_type));
-
- MOCK_METHOD1(OnApplicationFloodCallBack,
- void(const uint32_t&));
-
- MOCK_METHOD1(OnMalformedMessageCallback,
- void(const uint32_t&));
-
- MOCK_METHOD2(KeyFromPair,
- uint32_t(
- transport_manager::ConnectionUID connection_handle,
- uint8_t sessionId));
- MOCK_METHOD3(PairFromKey,
- void(
- uint32_t key,
- transport_manager::ConnectionUID* connection_handle,
- uint8_t* sessionId));
- MOCK_METHOD4(GetDataOnSessionKey,
- int32_t(uint32_t key,
- uint32_t* app_id,
- std::list<int32_t>* sessions_list,
- uint32_t* device_id));
-
- MOCK_METHOD4(GetDataOnDeviceID,
- int32_t(
- uint32_t device_handle,
- std::string* device_name,
- std::list<uint32_t>* applications_list,
- std::string* mac_address));
-
- MOCK_METHOD5(GetDataOnDeviceID,
- int32_t(
- uint32_t device_handle,
- std::string *device_name,
- std::list<uint32_t> *applications_list,
- std::string *mac_address,
- std::string *connection_type));
-
- MOCK_METHOD2(IsHeartBeatSupported,
- bool( transport_manager::ConnectionUID connection_handle,
- uint8_t session_id));
-
- MOCK_METHOD3(ProtocolVersionUsed,
- bool(uint32_t connection_id, uint8_t session_id,
- uint8_t& protocol_version));
-};
-/*
- * MOCK implementation of protocol_handler::ProtocolObserver interface
- */
-class ProtocoloObserverMock : public protocol_handler::ProtocolHandler {
- public:
- MOCK_METHOD2(SendMessageToMobileApp,
- void(const protocol_handler::RawMessagePtr message,
- bool final_message));
- MOCK_METHOD1(AddProtocolObserver,
- void(protocol_handler::ProtocolObserver* observer));
- MOCK_METHOD1(RemoveProtocolObserver,
- void(protocol_handler::ProtocolObserver* observer));
- MOCK_METHOD2(SendFramesNumber,
- void(uint32_t connection_key, int32_t number_of_frames));
- MOCK_METHOD2(SendHeartBeat,
- void(int32_t connection_id, uint8_t session_id));
- MOCK_METHOD2(SendEndSession,
- void(int32_t connection_id, uint8_t session_id));
-};
-/*
- * MOCK implementation of security_manager::SSLContext interface
- */
-class CryptoManagerMock : public security_manager::CryptoManager {
- public:
- MOCK_METHOD6(Init,
- bool (security_manager::Mode mode,
- security_manager::Protocol protocol,
- const std::string& cert_filename,
- const std::string& key_filename,
- const std::string& ciphers_list,
- bool verify_peer));
- MOCK_METHOD0(Finish,
- void ());
- MOCK_METHOD0(CreateSSLContext,
- security_manager::SSLContext* ());
- MOCK_METHOD1(ReleaseSSLContext,
- void(security_manager::SSLContext*));
- MOCK_CONST_METHOD0(LastError,
- std::string());
-};
-/*
- * MOCK implementation of security_manager::SSLContext interface
- */
-class SSLContextMock : public security_manager::SSLContext {
- public:
- MOCK_CONST_METHOD0(mode, int ());
- MOCK_METHOD2(StartHandshake,
- security_manager::SSLContext::HandshakeResult (
- const uint8_t** const, size_t*));
- MOCK_METHOD4(DoHandshakeStep,
- security_manager::SSLContext::HandshakeResult (
- const uint8_t* const, size_t,
- const uint8_t** const, size_t*));
- MOCK_METHOD4(Encrypt,
- bool (const uint8_t* const, size_t,
- const uint8_t** const, size_t*));
- MOCK_METHOD4(Decrypt,
- bool (const uint8_t* const, size_t,
- const uint8_t** const, size_t*));
- MOCK_CONST_METHOD1(get_max_block_size, size_t (size_t));
- MOCK_CONST_METHOD0(IsInitCompleted, bool());
- MOCK_CONST_METHOD0(IsHandshakePending, bool());
- MOCK_CONST_METHOD0(LastError,
- std::string());
-};
-/*
- * MOCK implementation of security_manager::SecurityManagerListener
- */
-class SMListenerMock : public security_manager::SecurityManagerListener {
- public:
- MOCK_METHOD2(OnHandshakeDone,
- bool(uint32_t connection_key,
- bool success));
-};
-
-/*
- * Matcher for RawMessages
- * Check binary data of RawMessages
- */
-MATCHER_P2(RawMessageEq, exp_data, exp_data_size,
- std::string(negation ? "is not" : "is") + " RawMessages "){
- const size_t arg_data_size = arg->data_size();
- if (arg_data_size != exp_data_size) {
- *result_listener << "Got " << arg_data_size << " bytes "
- << " expected " << exp_data_size << " bytes";
- return false;
- }
- const uint8_t *arg_data = arg->data();
- for (int i = 0; i < arg_data_size; ++i) {
- if (arg_data[i] != exp_data[i]) {
- *result_listener << "Fail in " << i << " byte";
- return false;
- }
- }
- return true;
-}
-
-/*
- * Matcher for checking RawMessage with InternalError Query
- * Check error id
- */
-MATCHER_P(InternalErrorWithErrId, expectedErrorId,
- std::string(negation ? "is not" : "is")
- + " InternalError with selected error" ){
- const size_t header_size = sizeof(security_manager::SecurityQuery::QueryHeader);
- if (arg->data_size() <= header_size) {
- *result_listener << "Size " << arg->data_size()
- << " bytes less or equal sizeof(QueryHeader)="
- << header_size;
- return false;
- }
- const uint8_t *data = arg->data();
- const uint8_t query_type = data[0];
- if (security_manager::SecurityQuery::NOTIFICATION != query_type) {
- *result_listener << "RawMessage is not notification, type=0x"
- << std::hex << static_cast<int>(query_type);
- return false;
- }
- // Read Big-Endian number
- const uint32_t query_id = data[1] << 16 |
- data[2] << 8 |
- data[3];
- if (security_manager::SecurityQuery::SEND_INTERNAL_ERROR != query_id) {
- *result_listener << "Notification is not InternalError, id=0x"
- << std::hex << query_id;
- return false;
- }
- const uint32_t json_size = data[8] << 24 |
- data[9] << 16 |
- data[10] << 8 |
- data[11];
- if (header_size + json_size >= arg->data_size()) {
- *result_listener << "InternalError contains only JSON data.";
- return false;
- }
- // Read err_id as bin data number
- const uint8_t* err_id =
- reinterpret_cast<const uint8_t*>(data + header_size + json_size);
- if (expectedErrorId != *err_id) {
- *result_listener << "InternalError id " << static_cast<int>(*err_id)
- << " and not equal error " << expectedErrorId;
- return false;
- }
- return true;
-}
-
-} // namespace security_manager_test
-} // namespace components
-} // namespace test
-/*
- * Matcher for checking QueryHeader equal in GTests
- */
-::testing::AssertionResult QueryHeader_EQ(
- const char* m_expr, const char* n_expr,
- const ::security_manager::SecurityQuery::QueryHeader& q1,
- const ::security_manager::SecurityQuery::QueryHeader& q2);
-
-#endif // TEST_COMPONENTS_SECURITY_MANAGER_INCLUDE_SECURITY_MANAGER_SECURITY_MANAGER_MOCK_H_
diff --git a/src/components/security_manager/test/mycert.pem b/src/components/security_manager/test/mycert.pem
new file mode 100644
index 0000000000..fe8be6970e
--- /dev/null
+++ b/src/components/security_manager/test/mycert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDlDCCAnwCCQDIe7AwFpWRlDANBgkqhkiG9w0BAQUFADCBizELMAkGA1UEBhMC
+UlUxEzARBgNVBAgMClNvbWUtU3RhdGUxGTAXBgNVBAcMEFNhaW50LVBldGVyc2J1
+cmcxDzANBgNVBAoMBkx1eG9mdDEXMBUGA1UEAwwORG1pdHJ5IENobWVyZXYxIjAg
+BgkqhkiG9w0BCQEWE2RjaG1lcmV2QGx1eG9mdC5jb20wHhcNMTQwMjI1MDkxODUz
+WhcNMTYxMTIyMDkxODUzWjCBizELMAkGA1UEBhMCUlUxEzARBgNVBAgMClNvbWUt
+U3RhdGUxGTAXBgNVBAcMEFNhaW50LVBldGVyc2J1cmcxDzANBgNVBAoMBkx1eG9m
+dDEXMBUGA1UEAwwORG1pdHJ5IENobWVyZXYxIjAgBgkqhkiG9w0BCQEWE2RjaG1l
+cmV2QGx1eG9mdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCn
+Mu9wNmXKaKOnefSv5iT8G2ESLjq+eYlxys/XAnDfkmnlgGYAcPno+XMhRj/lNV/c
+3A0L/R4631GFJA8vaM8m9Bn47FrPP4AXIHEQh9acA4qXiLfhhA8+9PPt4xVkjQYj
+bmexBLqDvRgT3MJwwFecUn/UABBlVZRCspn+6DkjiodbgmBOqyi1p0ng8BFeUbEH
++fLQVILCX3pjnMiP2bBtvq/7njgZT2luVtAAcOdRwRTuZT0YbgaXrHYsOa6VYDl1
+I0uOcdD8qENBXtBnykEqH+jZtKu6Rej1DsGOYWqz3AAaGiR1GJauNBxh+4v+i/eB
+0aCIA8T8qUqyuVVg48S/AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBACliraOJYijK
+yS+Sl6S6pFRqdF/evPdYF6zDJlM3P+/9qHoEy751vbBTzRkVbC/azyiZLwQMuyED
+6oCpkI7MqnrRip1ZelGx9K7ChaHOpX/QRN+3eqiDhzvMTGd2nPJf9np4xi8SJpGP
+UUROYI5fToIY5MaOKuOIR2a6c8xIuLWMG1XKJxXrRetLJZDgBqQPkuqaZIjYCY+q
+HQRjNUFNX4Mc453tKd90gFLGI3fxs1fJDIRSGfKJsj0qc+amSz4Sgiz4QUBcUQKd
+hJxUpStYhliZGZchEopLsShtIGfKKFaaPCIOTpVAwSr1oIDm9lpkdxeuQfedKT5f
+ZZmkez2pAF8=
+-----END CERTIFICATE-----
diff --git a/src/components/security_manager/test/mykey.pem b/src/components/security_manager/test/mykey.pem
new file mode 100644
index 0000000000..20c89546b4
--- /dev/null
+++ b/src/components/security_manager/test/mykey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEApzLvcDZlymijp3n0r+Yk/BthEi46vnmJccrP1wJw35Jp5YBm
+AHD56PlzIUY/5TVf3NwNC/0eOt9RhSQPL2jPJvQZ+Oxazz+AFyBxEIfWnAOKl4i3
+4YQPPvTz7eMVZI0GI25nsQS6g70YE9zCcMBXnFJ/1AAQZVWUQrKZ/ug5I4qHW4Jg
+TqsotadJ4PARXlGxB/ny0FSCwl96Y5zIj9mwbb6v+544GU9pblbQAHDnUcEU7mU9
+GG4Gl6x2LDmulWA5dSNLjnHQ/KhDQV7QZ8pBKh/o2bSrukXo9Q7BjmFqs9wAGhok
+dRiWrjQcYfuL/ov3gdGgiAPE/KlKsrlVYOPEvwIDAQABAoIBAQCAjkNXzhuZ87bR
+UI34qUYKqaqLZgw45A3v9naz5OaQoGzXz0+eSz98CECjdvYt8EoS8Qb/DtGthoOR
+kVYzp6yPUOSfZmu0Kij8ny8P/MHgF0D6nl50ASwPxhu/7vhF5cCwgXUswGwAWuYm
+b3j5ZIp4YV5zzNDOeWyTk+uf+UHltqFD7Ae4M9z58r17/OWhva5mtusTuuEYjzC6
+AE/fsOC0gLNSM4+SfclfCkHpH+GikzNMSQ2H0hlXllPmR73BoC6N6aoY5hQWBLV7
+LxtYbJqx7TAqRyypBQekjJe36roRetXtzy3i6V/y69045td5kk70cVjmFhl79475
+82rnRLHBAoGBANgq4axr5OotTUmPkGd0afoaWSRPJfiTTdNeMkqTzM6zIcVLSKhB
+78ERwdDD9FOu+Bgivg4DlpmH7ArWn8QNDtdkhmPfKYfTqX6qH7AK4cybvYICMlct
+EdW4TvKm/ZB3mrVOP9JVPjdyFMp+Je6N+qp1w+ui9mxX8pWnrC/+DfTvAoGBAMYC
+GFjnw/O9hjF2Mb00qUarmM+reJZMXv/pVik+cm0eAiYvgGvKbAYkIXwdb7rLBw9k
+baJmxP0PrAoXy5TpPdfROqPwrRCyReKymKkEZeTpONgD0s8MbX167ovZu1OQVKQo
+IyJeUzWa0kpglnbL2lLVu49x8jWHDJdYhmkDNE0xAoGAR4ux07qGMoe5693rYoJi
+TRgJZv4XSDWg7ZNgu9Q9VjBtvfoT2zSvoMw6xNkGdegUTxC4rLS9VKVrF48/o8ja
+n6my3T1QZpdEoxq1kDOZ1nm5eF03wii1nXH6F0/z3qvndZingPsbs4g7n2WvMkyl
+qWN+6++s9eEJ9kRftia1AdsCgYAUnU05nE97RcT9y0dcYmopMF5FaJ2yUBsn23wb
+6SNylsg0f4eIMVfTv9k4mbvzH4YJpTQAz2A81G/d0SJhy3Kj0GWhgcIS1eyOsHdS
+SWHuVhWT77n30lxnzu+c4bst9P3K5V7bCiTxlL/F/I5NqeV98ECJq5xC1F+MNiww
+LKQ6UQKBgC2zL59Vf8QnRkRN0gOUfs3ejrLcxFRzTXvcKqcHtbaqzCs3qSNC6UvV
+wjBazEwQCo1wnM81X8uT5fLhnjXebWtnYexQo5P38PiaqTQDgrbAdhP5P8NwRCXM
+G3SNEz0XeL27jmWjf0VJdwD0LuHXYhcwAWq4alhJ024rjgVHwOze
+-----END RSA PRIVATE KEY-----
diff --git a/src/components/security_manager/test/security_manager_test.cc b/src/components/security_manager/test/security_manager_test.cc
index 30f81ee62e..b5f9ae2e78 100644
--- a/src/components/security_manager/test/security_manager_test.cc
+++ b/src/components/security_manager/test/security_manager_test.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Ford Motor Company
+ * Copyright (c) 2015, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,30 +30,47 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <gtest/gtest.h>
#include <string>
+#include "gtest/gtest.h"
#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
+#include "protocol_handler/mock_protocol_handler.h"
+#include "protocol_handler/mock_session_observer.h"
+#include "security_manager/mock_security_manager.h"
+#include "security_manager/mock_ssl_context.h"
+#include "security_manager/mock_crypto_manager.h"
+#include "security_manager/mock_security_manager_listener.h"
+#include "utils/make_shared.h"
namespace test {
namespace components {
namespace security_manager_test {
-using namespace ::protocol_handler;
-using ::protocol_handler::ServiceType;
-using namespace ::transport_manager;
-using namespace ::security_manager;
+using protocol_handler::PROTOCOL_VERSION_2;
+using protocol_handler::ServiceType;
+using protocol_handler::kControl;
+using protocol_handler::kRpc;
+using protocol_handler::kAudio;
+using protocol_handler::kMobileNav;
+using protocol_handler::kBulk;
+using protocol_handler::kInvalidServiceType;
+using protocol_handler::RawMessagePtr;
+using protocol_handler::RawMessage;
+
+using security_manager::SecurityQuery;
+using security_manager::SSLContext;
+using security_manager::SecurityManager;
+using security_manager::SecurityManagerImpl;
+
+using security_manager_test::InternalErrorWithErrId;
+using ::testing::Return;
+using ::testing::ReturnNull;
+using ::testing::DoAll;
+using ::testing::SetArgPointee;
+using ::testing::_;
// Sample data for handshake data emulation
const int32_t key = 0x1;
@@ -62,24 +79,14 @@ 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]);
+const uint8_t handshake_data[] = {0x1, 0x2, 0x3, 0x4, 0x5};
+const size_t handshake_data_size =
+ sizeof(handshake_data) / sizeof(handshake_data[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;
+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]);
class SecurityManagerTest : public ::testing::Test {
protected:
@@ -91,20 +98,22 @@ class SecurityManagerTest : public ::testing::Test {
}
void TearDown() OVERRIDE {
// Wait call methods in thread
- usleep(100000);
+ testing::Mock::AsyncVerifyAndClearExpectations(1000);
}
- void SetMockCryptoManger() {
+ void SetMockCryptoManager() {
+ EXPECT_CALL(mock_crypto_manager, IsCertificateUpdateRequired())
+ .WillRepeatedly(Return(false));
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,
+ 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));
+ const RawMessagePtr rawMessagePtr(utils::MakeShared<RawMessage>(
+ key, protocolVersion, data, dataSize, serviceType));
security_manager_->OnMessageReceived(rawMessagePtr);
}
/*
@@ -130,7 +139,7 @@ class SecurityManagerTest : public ::testing::Test {
/*
* Wrapper for fast emulate recieve Handshake
*/
- void EmulateMobileMessageHandShake(const uint8_t* const data,
+ void EmulateMobileMessageHandshake(const uint8_t* const data,
const uint32_t data_size,
const int repeat_count = 1) {
const SecurityQuery::QueryHeader header(SecurityQuery::NOTIFICATION,
@@ -142,12 +151,18 @@ class SecurityManagerTest : public ::testing::Test {
}
::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;
+ testing::StrictMock<protocol_handler_test::MockSessionObserver>
+ mock_session_observer;
+ testing::StrictMock<protocol_handler_test::MockProtocolHandler>
+ mock_protocol_handler;
+ testing::StrictMock<security_manager_test::MockCryptoManager>
+ mock_crypto_manager;
+ testing::StrictMock<security_manager_test::MockSSLContext>
+ mock_ssl_context_new;
+ testing::StrictMock<security_manager_test::MockSSLContext>
+ mock_ssl_context_exists;
+ testing::StrictMock<security_manager_test::MockSecurityManagerListener>
+ mock_sm_listener;
};
// Test Bodies
@@ -186,12 +201,14 @@ TEST_F(SecurityManagerTest, Listeners_NoListeners) {
security_manager_->RemoveListener(&mock_sm_listener);
// Expect no calls
- testing::StrictMock<SMListenerMock> mock_listener2;
+ testing::StrictMock<MockSecurityManagerListener> mock_listener2;
security_manager_->AddListener(&mock_listener2);
security_manager_->RemoveListener(&mock_listener2);
- security_manager_->NotifyListenersOnHandshakeDone(key, true);
- security_manager_->NotifyListenersOnHandshakeDone(key, false);
+ security_manager_->NotifyListenersOnHandshakeDone(
+ key, SSLContext::Handshake_Result_Success);
+ security_manager_->NotifyListenersOnHandshakeDone(
+ key, SSLContext::Handshake_Result_Fail);
}
/*
* Notifying two listeners
@@ -200,23 +217,32 @@ 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;
+ testing::StrictMock<MockSecurityManagerListener> mock_listener1;
+ testing::StrictMock<MockSecurityManagerListener> mock_listener2;
- const bool first_call_value = true;
+ const SSLContext::HandshakeResult first_call_value =
+ SSLContext::Handshake_Result_Success;
// 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(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));
+
+ // First listener was not removed from listener list
+ // So this callback wil lbe either call.
+ EXPECT_CALL(mock_listener1, OnCertificateUpdateRequired());
+
+ const SSLContext::HandshakeResult second_call_value =
+ SSLContext::Handshake_Result_Fail;
// Expect call last listener on 2d call
- EXPECT_CALL(mock_listener1, OnHandshakeDone(key, second_call_value)).
- // Emulate false (reject) result
- WillOnce(Return(true));
+ EXPECT_CALL(mock_listener1, OnHandshakeDone(key, second_call_value))
+ .
+ // Emulate false (reject) result
+ WillOnce(Return(true));
// Expect no call 3d call
@@ -224,11 +250,16 @@ TEST_F(SecurityManagerTest, Listeners_Notifying) {
security_manager_->AddListener(&mock_listener2);
// 1st call
security_manager_->NotifyListenersOnHandshakeDone(key, first_call_value);
+ security_manager_->NotifyOnCertififcateUpdateRequired();
// 2nd call
security_manager_->NotifyListenersOnHandshakeDone(key, second_call_value);
+ security_manager_->NotifyOnCertififcateUpdateRequired();
// 3nd call
- security_manager_->NotifyListenersOnHandshakeDone(key, false);
+ security_manager_->NotifyListenersOnHandshakeDone(
+ key, SSLContext::Handshake_Result_Fail);
+ security_manager_->NotifyOnCertififcateUpdateRequired();
}
+
/*
* SecurityManager with NULL CryptoManager shall send
* InternallError (ERROR_NOT_SUPPORTED) on any Query
@@ -237,14 +268,16 @@ 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;
+ // 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_session_observer,
+ ProtocolVersionUsed(connection_id, session_id, _))
+ .WillOnce(Return(true));
- EXPECT_CALL(
- mock_protocol_handler,
- SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_NOT_SUPPORTED), is_final));
+ 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);
@@ -255,8 +288,9 @@ TEST_F(SecurityManagerTest, SecurityManager_NULLCryptoManager) {
* Shall skip all OnMobileMessageSent
*/
TEST_F(SecurityManagerTest, OnMobileMessageSent) {
- const ::protocol_handler::RawMessagePtr rawMessagePtr(
- new ::protocol_handler::RawMessage(key, protocolVersion, NULL, 0));
+ const uint8_t* data_param = NULL;
+ const RawMessagePtr rawMessagePtr(
+ utils::MakeShared<RawMessage>(key, protocolVersion, data_param, 0));
security_manager_->OnMobileMessageSent(rawMessagePtr);
}
/*
@@ -276,14 +310,17 @@ TEST_F(SecurityManagerTest, GetWrongServiceType) {
TEST_F(SecurityManagerTest, GetEmptyQuery) {
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_session_observer,
+ ProtocolVersionUsed(connection_id, session_id, _))
+ .WillOnce(Return(true));
- EXPECT_CALL(
- mock_protocol_handler,
- SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_INVALID_QUERY_SIZE), is_final));
+ EXPECT_CALL(
+ mock_protocol_handler,
+ SendMessageToMobileApp(
+ InternalErrorWithErrId(SecurityManager::ERROR_INVALID_QUERY_SIZE),
+ is_final));
// Call with NULL data
call_OnMessageReceived(NULL, 0, secureServiceType);
}
@@ -291,20 +328,22 @@ TEST_F(SecurityManagerTest, GetEmptyQuery) {
* Shall send InternallError on null data recieved
*/
TEST_F(SecurityManagerTest, GetWrongJSONSize) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_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);
+ 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);
}
@@ -312,20 +351,22 @@ TEST_F(SecurityManagerTest, GetWrongJSONSize) {
* Shall send InternallError on INVALID_QUERY_ID
*/
TEST_F(SecurityManagerTest, GetInvalidQueryId) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_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);
+ 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);
}
@@ -334,111 +375,121 @@ TEST_F(SecurityManagerTest, GetInvalidQueryId) {
* CreateSSLContext for already protected connections
*/
TEST_F(SecurityManagerTest, CreateSSLContext_ServiceAlreadyProtected) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
// Return mock SSLContext
- EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl)).
- WillOnce(Return(&mock_ssl_context_new));
+ 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);
+ const SSLContext* result = security_manager_->CreateSSLContext(key);
+ EXPECT_EQ(&mock_ssl_context_new, result);
}
/*
* Shall send Internall Error on error create SSL
*/
TEST_F(SecurityManagerTest, CreateSSLContext_ErrorCreateSSL) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
// Expect InternalError with ERROR_ID
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_session_observer,
+ ProtocolVersionUsed(connection_id, session_id, _))
+ .WillOnce(Return(true));
EXPECT_CALL(
- mock_protocol_handler,
- SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_INTERNAL), is_final));
+ 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());
+ 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);
+ const SSLContext* result = security_manager_->CreateSSLContext(key);
+ EXPECT_EQ(NULL, result);
}
/*
* Shall send InternalError with SERVICE_NOT_FOUND
* on getting any Error with call SetSSLContext
*/
TEST_F(SecurityManagerTest, CreateSSLContext_SetSSLContextError) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
// Expect InternalError with ERROR_ID
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_session_observer,
+ ProtocolVersionUsed(connection_id, session_id, _))
+ .WillOnce(Return(true));
EXPECT_CALL(
- mock_protocol_handler,
- SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_UNKWOWN_INTERNAL_ERROR), is_final));
+ mock_protocol_handler,
+ SendMessageToMobileApp(
+ InternalErrorWithErrId(SecurityManager::ERROR_UNKNOWN_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_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));
+ EXPECT_CALL(mock_session_observer, SetSSLContext(key, &mock_ssl_context_new))
+ .WillOnce(Return(SecurityManager::ERROR_UNKNOWN_INTERNAL_ERROR));
- const bool rezult = security_manager_->CreateSSLContext(key);
- EXPECT_FALSE(rezult);
+ const SSLContext* result = security_manager_->CreateSSLContext(key);
+ EXPECT_EQ(NULL, result);
}
/*
* Shall protect connection on correct call CreateSSLContext
*/
TEST_F(SecurityManagerTest, CreateSSLContext_Success) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
// 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()).
+ 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));
+ 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);
+ const SSLContext* result = security_manager_->CreateSSLContext(key);
+ EXPECT_EQ(&mock_ssl_context_new, result);
}
/*
* Shall send InternallError on call StartHandshake for uprotected service
*/
TEST_F(SecurityManagerTest, StartHandshake_ServiceStillUnprotected) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_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_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));
+ 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(ReturnNull());
+ EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl))
+ .WillOnce(ReturnNull());
security_manager_->StartHandshake(key);
}
@@ -446,32 +497,38 @@ TEST_F(SecurityManagerTest, StartHandshake_ServiceStillUnprotected) {
* Shall send InternallError on SSL error and notify listeners
*/
TEST_F(SecurityManagerTest, StartHandshake_SSLInternalError) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_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));
+ 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));
+ 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, StartHandshake(_, _)).
- WillOnce(DoAll(SetArgPointee<0>(handshake_data_out_pointer),
- SetArgPointee<1>(handshake_data_out_size),
- Return(security_manager::SSLContext::
- Handshake_Result_Fail)));
+ 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)));
security_manager_->StartHandshake(key);
}
@@ -479,59 +536,67 @@ TEST_F(SecurityManagerTest, StartHandshake_SSLInternalError) {
* Shall send data on call StartHandshake
*/
TEST_F(SecurityManagerTest, StartHandshake_SSLInitIsNotComplete) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_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_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, 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(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)));
+ 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
+ * Shall notify listeners on call StartHandshake after SSLContext initialization
+ * complete
*/
TEST_F(SecurityManagerTest, StartHandshake_SSLInitIsComplete) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
// Expect no message send
// Expect notifying listeners (success)
- EXPECT_CALL(mock_sm_listener, OnHandshakeDone(key, true)).
- WillOnce(Return(true));
+ 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));
+ EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl))
+ .WillOnce(Return(&mock_ssl_context_exists));
+ EXPECT_CALL(mock_ssl_context_exists, IsInitCompleted())
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_crypto_manager, IsCertificateUpdateRequired())
+ .WillOnce(Return(false));
security_manager_->StartHandshake(key);
}
@@ -540,19 +605,22 @@ TEST_F(SecurityManagerTest, StartHandshake_SSLInitIsComplete) {
* getting SEND_HANDSHAKE_DATA with NULL data
*/
TEST_F(SecurityManagerTest, ProccessHandshakeData_WrongDataSize) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_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);
+ mock_protocol_handler,
+ SendMessageToMobileApp(
+ InternalErrorWithErrId(SecurityManager::ERROR_INVALID_QUERY_SIZE),
+ is_final));
+ EmulateMobileMessageHandshake(NULL, 0);
}
/*
* Shall send InternallError on
@@ -560,28 +628,32 @@ TEST_F(SecurityManagerTest, ProccessHandshakeData_WrongDataSize) {
* for service which is not protected
*/
TEST_F(SecurityManagerTest, ProccessHandshakeData_ServiceNotProtected) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
// Expect InternalError with ERROR_ID
uint32_t connection_id = 0;
uint8_t session_id = 0;
- //uint8_t protocol_version = 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_session_observer,
+ ProtocolVersionUsed(connection_id, session_id, _))
+ .WillOnce(Return(true));
EXPECT_CALL(
- mock_protocol_handler,
- SendMessageToMobileApp( InternalErrorWithErrId( SecurityManager::ERROR_SERVICE_NOT_PROTECTED), is_final));
+ 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));
+ 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(ReturnNull());
+ EXPECT_CALL(mock_session_observer, GetSSLContext(key, kControl))
+ .WillOnce(ReturnNull());
const uint8_t data[] = {0x1, 0x2};
- EmulateMobileMessageHandShake(data, sizeof(data)/sizeof(data[0]));
+ EmulateMobileMessageHandshake(data, sizeof(data) / sizeof(data[0]));
}
/*
* Shall send InternallError on getting
@@ -589,235 +661,237 @@ TEST_F(SecurityManagerTest, ProccessHandshakeData_ServiceNotProtected) {
* data (DoHandshakeStep return NULL pointer)
*/
TEST_F(SecurityManagerTest, ProccessHandshakeData_InvalidData) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
// 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));
+ // 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);
+ 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));
+ EXPECT_CALL(mock_sm_listener,
+ OnHandshakeDone(key, SSLContext::Handshake_Result_Fail))
+ .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_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)));
-
+ mock_ssl_context_exists,
+ DoHandshakeStep(HandshakeStepEq(handshake_data, handshake_data_size),
+ handshake_data_size,
+ _,
+ _))
+ .WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(SSLContext::Handshake_Result_AbnormalFail)))
+ .WillOnce(DoAll(SetArgPointee<2>((uint8_t*)NULL),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(SSLContext::Handshake_Result_AbnormalFail)))
+ .WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(0),
+ Return(SSLContext::Handshake_Result_AbnormalFail)))
+ .WillOnce(DoAll(SetArgPointee<2>((uint8_t*)NULL),
+ SetArgPointee<3>(0),
+ Return(SSLContext::Handshake_Result_AbnormalFail)));
// On each wrong handshake will be asked error
- EXPECT_CALL(mock_ssl_context_exists, LastError()).
- Times(handshake_emulates);
+ 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);
+ 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();
+ SetMockCryptoManager();
// 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);
+ // 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));
+
+ // Get size of raw message after
+ const size_t raw_message_size = 15;
+ EXPECT_CALL(mock_protocol_handler,
+ SendMessageToMobileApp(RawMessageEqSize(raw_message_size),
+ is_final)).Times(handshake_emulates);
// Expect notifying listeners (unsuccess)
- EXPECT_CALL(mock_sm_listener, OnHandshakeDone(key, false)).
- WillOnce(Return(true));
+ EXPECT_CALL(mock_sm_listener,
+ OnHandshakeDone(key, SSLContext::Handshake_Result_Fail))
+ .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));
+ 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);
+ mock_ssl_context_exists,
+ DoHandshakeStep(HandshakeStepEq(handshake_data, handshake_data_size),
+ handshake_data_size,
+ _,
+ _))
+ .WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(SSLContext::Handshake_Result_Success)))
+ .WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(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();
+TEST_F(SecurityManagerTest, ProccessHandshakeData_HandshakeFinished) {
+ SetMockCryptoManager();
// 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));
+ EXPECT_CALL(mock_sm_listener,
+ OnHandshakeDone(key, SSLContext::Handshake_Result_Success))
+ .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));
+
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)));
+ mock_ssl_context_exists,
+ DoHandshakeStep(HandshakeStepEq(handshake_data, handshake_data_size),
+ handshake_data_size,
+ _,
+ _))
+ .
+ // two states with correct out data
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(SSLContext::Handshake_Result_Success)))
+ .WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(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(SSLContext::Handshake_Result_Success)))
+ .WillOnce(DoAll(SetArgPointee<2>((uint8_t*)NULL),
+ SetArgPointee<3>(handshake_data_out_size),
+ Return(SSLContext::Handshake_Result_Fail)))
+ .
+ // two states with with null data size
+ WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(0),
+ Return(SSLContext::Handshake_Result_Success)))
+ .WillOnce(DoAll(SetArgPointee<2>(handshake_data_out_pointer),
+ SetArgPointee<3>(0),
+ Return(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));
+ // 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_CALL(mock_protocol_handler, SendMessageToMobileApp(_, is_final))
+ .Times(2);
// Expect NO InternalError with ERROR_ID
- EmulateMobileMessageHandShake(handshake_data, handshake_data_size, handshake_emulates);
+ EmulateMobileMessageHandshake(
+ handshake_data, handshake_data_size, handshake_emulates);
}
/*
* Shall not any query on getting empty SEND_INTERNAL_ERROR
*/
TEST_F(SecurityManagerTest, GetInternalError_NullData) {
- SetMockCryptoManger();
+ SetMockCryptoManager();
- const SecurityQuery::QueryHeader header( SecurityQuery::NOTIFICATION,
- SecurityQuery::SEND_INTERNAL_ERROR, 0);
+ 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();
+ SetMockCryptoManager();
- const SecurityQuery::QueryHeader header( SecurityQuery::NOTIFICATION,
- SecurityQuery::SEND_INTERNAL_ERROR, 0);
+ 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]));
+ 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();
+ SetMockCryptoManager();
- SecurityQuery::QueryHeader header( SecurityQuery::NOTIFICATION,
- SecurityQuery::SEND_INTERNAL_ERROR, 0);
+ 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());
+ 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();
+ SetMockCryptoManager();
- SecurityQuery::QueryHeader header( SecurityQuery::NOTIFICATION,
- SecurityQuery::SEND_INTERNAL_ERROR, 0);
+ 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());
+ EmulateMobileMessage(
+ header, reinterpret_cast<const uint8_t*>(error.c_str()), error.size());
}
-} // namespace security_manager_test
-} // namespace components
-} // namespace test
+} // namespace security_manager_test
+} // namespace components
+} // namespace test
diff --git a/src/components/security_manager/test/security_query_matcher.cc b/src/components/security_manager/test/security_query_matcher.cc
index 2320e83439..3b7f4dd298 100644
--- a/src/components/security_manager/test/security_query_matcher.cc
+++ b/src/components/security_manager/test/security_query_matcher.cc
@@ -30,8 +30,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <gmock/gmock.h>
#include <string>
+
+#include "gmock/gmock.h"
#include "utils/byte_order.h"
#include "security_manager/security_query.h"
@@ -43,81 +44,80 @@ namespace security_manager_test {
* Matcher for checking RawMessage with InternalError Query
* Check error id
*/
-MATCHER_P(InternalErrorWithErrId, expectedErrorId,
- std::string(negation ? "is not" : "is")
- + " InternalError with selected error" ){
+MATCHER_P(InternalErrorWithErrId,
+ expectedErrorId,
+ std::string(negation ? "is not" : "is") +
+ " InternalError with selected error") {
const size_t header_size =
- sizeof(security_manager::SecurityQuery::QueryHeader);
+ sizeof(security_manager::SecurityQuery::QueryHeader);
if (arg->data_size() <= header_size) {
*result_listener << "Size " << arg->data_size()
- << " bytes less or equal sizeof(QueryHeader)="
- << header_size;
+ << " bytes less or equal sizeof(QueryHeader)="
+ << header_size;
return false;
}
- const uint8_t *data = arg->data();
+ const uint8_t* data = arg->data();
const uint8_t query_type = data[0];
if (security_manager::SecurityQuery::NOTIFICATION != query_type) {
- *result_listener << "RawMessage is not notification, type=0x"
- << std::hex << static_cast<int>(query_type);
+ *result_listener << "RawMessage is not notification, type=0x" << std::hex
+ << static_cast<int>(query_type);
return false;
}
// Read Big-Endian number
- const uint32_t query_id = data[1] << 16 |
- data[2] << 8 |
- data[3];
+ const uint32_t query_id = data[1] << 16 | data[2] << 8 | data[3];
if (security_manager::SecurityQuery::SEND_INTERNAL_ERROR != query_id) {
- *result_listener << "Notification is not InternalError, id=0x"
- << std::hex << query_id;
+ *result_listener << "Notification is not InternalError, id=0x" << std::hex
+ << query_id;
return false;
}
- const uint32_t json_size = data[8] << 24 |
- data[9] << 16 |
- data[10] << 8 |
- data[11];
+ const uint32_t json_size =
+ data[8] << 24 | data[9] << 16 | data[10] << 8 | data[11];
if (header_size + json_size >= arg->data_size()) {
*result_listener << "InternalError contains only JSON data.";
return false;
}
// Read err_id as bin data number
- const uint8_t *err_id =
- reinterpret_cast<const uint8_t *>(data + header_size + json_size);
+ const uint8_t* err_id =
+ reinterpret_cast<const uint8_t*>(data + header_size + json_size);
if (expectedErrorId != *err_id) {
*result_listener << "InternalError id " << static_cast<int>(*err_id)
- << " and not equal error " << expectedErrorId;
+ << " and not equal error " << expectedErrorId;
return false;
}
return true;
}
-} // namespace security_manager_test
-} // namespace components
-} // namespace test
-/*
- * Matcher for checking QueryHeader equal in GTests
- */
+} // namespace security_manager_test
+} // namespace components
+} // namespace test
+ /*
+ * Matcher for checking QueryHeader equal in GTests
+ */
::testing::AssertionResult QueryHeader_EQ(
- const char *m_expr, const char *n_expr,
- const ::security_manager::SecurityQuery::QueryHeader &q1,
- const ::security_manager::SecurityQuery::QueryHeader &q2);
+ const char* m_expr,
+ const char* n_expr,
+ const ::security_manager::SecurityQuery::QueryHeader& q1,
+ const ::security_manager::SecurityQuery::QueryHeader& q2);
::testing::AssertionResult QueryHeader_EQ(
- const char* m_expr, const char* n_expr,
- const ::security_manager::SecurityQuery::QueryHeader& q1,
- const ::security_manager::SecurityQuery::QueryHeader& q2) {
+ const char* m_expr,
+ const char* n_expr,
+ const ::security_manager::SecurityQuery::QueryHeader& q1,
+ const ::security_manager::SecurityQuery::QueryHeader& q2) {
::testing::AssertionResult fail_result = ::testing::AssertionFailure();
fail_result << "(\"" << m_expr << " and \"" << n_expr << "\") are not equal "
<< " : different ";
if (q1.json_size != q2.json_size)
- return fail_result << "json_size_1=" << q1.json_size << ", json_size_2="
- << q2.json_size;
+ return fail_result << "json_size_1=" << q1.json_size
+ << ", json_size_2=" << q2.json_size;
if (q1.query_id != q2.query_id)
- return fail_result << "query_id_1=" << q1.query_id << ", query_id_2="
- << q2.query_id;
+ return fail_result << "query_id_1=" << q1.query_id
+ << ", query_id_2=" << q2.query_id;
if (q1.query_type != q2.query_type)
- return fail_result << "query_type_1=" << q1.query_type << ", query_type_2="
- << q2.query_type;
+ return fail_result << "query_type_1=" << q1.query_type
+ << ", query_type_2=" << q2.query_type;
if (q1.seq_number != q2.seq_number)
- return fail_result << "seq_number_1=" << q1.seq_number << ", seq_number_2="
- << q2.seq_number;
+ return fail_result << "seq_number_1=" << q1.seq_number
+ << ", seq_number_2=" << q2.seq_number;
return ::testing::AssertionSuccess();
}
diff --git a/src/components/security_manager/test/security_query_test.cc b/src/components/security_manager/test/security_query_test.cc
index 6db076fd52..80da10ea72 100644
--- a/src/components/security_manager/test/security_query_test.cc
+++ b/src/components/security_manager/test/security_query_test.cc
@@ -30,16 +30,17 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <gtest/gtest.h>
#include <vector>
#include <string>
+
+#include "gtest/gtest.h"
#include "security_manager/security_query.h"
#include "protocol_handler/protocol_payload.h"
#include "utils/byte_order.h"
-#include "include/security_manager_mock.h"
+#include "security_manager/mock_security_manager.h"
// Test values for compare after serialization and byteorder conversion
-#define SEQ_NUMBER 0x12345678u
+#define SEQ_NUMBER 0x12345678u
#define CONNECTION_KEY 0xABCDEF0u
namespace test {
@@ -68,7 +69,7 @@ class SecurityQueryTest : public ::testing::Test {
* Used for handling header and data array to byte array for serialization
*/
std::vector<uint8_t> DeserializeData(SecurityQuery::QueryHeader header,
- const uint8_t * const binary_data,
+ const uint8_t* const binary_data,
const size_t bin_data_size) const {
// convert to Big-Endian (network) order
const uint32_t query_id = header.query_id << 8;
@@ -91,8 +92,8 @@ class SecurityQueryTest : public ::testing::Test {
* for correct working on Mobile side (3*8 byte)
*/
TEST_F(SecurityQueryTest, Equal_RPCHeader) {
- ASSERT_EQ(sizeof(SecurityQuery::QueryHeader)*8,
- ::protocol_handler::ProtocolPayloadV2SizeBits());
+ ASSERT_EQ(sizeof(SecurityQuery::QueryHeader) * 8,
+ ::protocol_handler::ProtocolPayloadV2SizeBits());
}
/*
* Security QueryHeader default construction
@@ -107,16 +108,16 @@ TEST_F(SecurityQueryTest, QueryHeaderConstructor) {
*/
TEST_F(SecurityQueryTest, QueryHeaderConstructor2) {
SecurityQuery::QueryHeader new_header(SecurityQuery::NOTIFICATION,
- SecurityQuery::SEND_HANDSHAKE_DATA,
- SEQ_NUMBER);
+ SecurityQuery::SEND_HANDSHAKE_DATA,
+ SEQ_NUMBER);
ASSERT_EQ(new_header.query_type, SecurityQuery::NOTIFICATION);
ASSERT_EQ(new_header.query_id, SecurityQuery::SEND_HANDSHAKE_DATA);
ASSERT_EQ(new_header.seq_number, SEQ_NUMBER);
ASSERT_EQ(new_header.json_size, 0u);
SecurityQuery::QueryHeader new_header2(SecurityQuery::RESPONSE,
- SecurityQuery::SEND_INTERNAL_ERROR,
- SEQ_NUMBER + 1);
+ SecurityQuery::SEND_INTERNAL_ERROR,
+ SEQ_NUMBER + 1);
ASSERT_EQ(new_header2.query_type, SecurityQuery::RESPONSE);
ASSERT_EQ(new_header2.query_id, SecurityQuery::SEND_INTERNAL_ERROR);
ASSERT_EQ(new_header2.seq_number, SEQ_NUMBER + 1);
@@ -138,7 +139,7 @@ TEST_F(SecurityQueryTest, QueryConstructor) {
ASSERT_EQ(query.get_connection_key(), 0u);
ASSERT_EQ(query.get_data_size(), 0u);
- ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
ASSERT_TRUE(query.get_json_message().empty());
EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), invalid_header);
@@ -155,7 +156,7 @@ TEST_F(SecurityQueryTest, QueryConstructor2) {
ASSERT_EQ(query.get_connection_key(), CONNECTION_KEY);
ASSERT_EQ(query.get_data_size(), 0u);
- ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
ASSERT_TRUE(query.get_json_message().empty());
EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), init_header);
@@ -169,17 +170,14 @@ TEST_F(SecurityQueryTest, QueryConstructor2) {
*/
TEST_F(SecurityQueryTest, QueryConstructor3) {
uint8_t raw_data[] = {0x0, 0x1, 0x2};
- const size_t raw_data_size =
- sizeof(raw_data)/sizeof(raw_data[0]);
+ const size_t raw_data_size = sizeof(raw_data) / sizeof(raw_data[0]);
- SecurityQuery query(init_header,
- CONNECTION_KEY,
- raw_data, raw_data_size);
+ SecurityQuery query(init_header, CONNECTION_KEY, raw_data, raw_data_size);
ASSERT_EQ(query.get_connection_key(), CONNECTION_KEY);
ASSERT_EQ(query.get_data_size(), raw_data_size);
// query shall handle own array of byte data
- ASSERT_NE(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_NE(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
for (size_t i = 0; i < raw_data_size; ++i) {
ASSERT_EQ(query.get_data()[i], raw_data[i]);
}
@@ -188,7 +186,7 @@ TEST_F(SecurityQueryTest, QueryConstructor3) {
// Deserialization shall return vector equal header + data array
const std::vector<uint8_t> vector =
- DeserializeData(init_header, raw_data, raw_data_size);
+ DeserializeData(init_header, raw_data, raw_data_size);
const std::vector<uint8_t> deserialize_vector = query.DeserializeQuery();
ASSERT_EQ(deserialize_vector, vector);
}
@@ -198,8 +196,7 @@ TEST_F(SecurityQueryTest, QueryConstructor3) {
TEST_F(SecurityQueryTest, Setters) {
const std::string str = "test example string";
uint8_t raw_data[] = {0x6, 0x7, 0x8};
- const size_t raw_data_size =
- sizeof(raw_data)/sizeof(raw_data[0]);
+ const size_t raw_data_size = sizeof(raw_data) / sizeof(raw_data[0]);
SecurityQuery query;
query.set_connection_key(CONNECTION_KEY);
@@ -210,7 +207,7 @@ TEST_F(SecurityQueryTest, Setters) {
ASSERT_EQ(query.get_connection_key(), CONNECTION_KEY);
ASSERT_EQ(query.get_data_size(), raw_data_size);
// query shall handle own array of byte data
- ASSERT_NE(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_NE(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
for (size_t i = 0; i < raw_data_size; ++i) {
ASSERT_EQ(query.get_data()[i], raw_data[i]);
}
@@ -228,7 +225,7 @@ TEST_F(SecurityQueryTest, Parse_NullData) {
// check side-effects
ASSERT_EQ(query.get_connection_key(), 0u);
ASSERT_EQ(query.get_data_size(), 0u);
- ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
ASSERT_TRUE(query.get_json_message().empty());
EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), invalid_header);
}
@@ -245,7 +242,7 @@ TEST_F(SecurityQueryTest, Parse_LessHeaderData) {
// check side-effects
ASSERT_EQ(query.get_connection_key(), 0u);
ASSERT_EQ(query.get_data_size(), 0u);
- ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
ASSERT_TRUE(query.get_json_message().empty());
EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), invalid_header);
}
@@ -253,8 +250,7 @@ TEST_F(SecurityQueryTest, Parse_LessHeaderData) {
* SecurityQuery serializes data equal header size
*/
TEST_F(SecurityQueryTest, Parse_HeaderData) {
- const std::vector<uint8_t> vector =
- DeserializeData(init_header, NULL, 0u);
+ const std::vector<uint8_t> vector = DeserializeData(init_header, NULL, 0u);
SecurityQuery query;
const bool result = query.SerializeQuery(&vector[0], vector.size());
@@ -263,7 +259,7 @@ TEST_F(SecurityQueryTest, Parse_HeaderData) {
// check side-effects
ASSERT_EQ(query.get_connection_key(), 0u);
ASSERT_EQ(query.get_data_size(), 0u);
- ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
ASSERT_TRUE(query.get_json_message().empty());
EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), init_header);
@@ -277,8 +273,7 @@ TEST_F(SecurityQueryTest, Parse_HeaderData) {
TEST_F(SecurityQueryTest, Parse_HeaderDataWrong) {
// Wrong json size
init_header.json_size = 0x0FFFFFFF;
- const std::vector<uint8_t> vector =
- DeserializeData(init_header, NULL, 0u);
+ const std::vector<uint8_t> vector = DeserializeData(init_header, NULL, 0u);
SecurityQuery query;
const bool result = query.SerializeQuery(&vector[0], vector.size());
@@ -287,7 +282,7 @@ TEST_F(SecurityQueryTest, Parse_HeaderDataWrong) {
// check side-effects
ASSERT_EQ(query.get_connection_key(), 0u);
ASSERT_EQ(query.get_data_size(), 0u);
- ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
ASSERT_TRUE(query.get_json_message().empty());
EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), init_header);
@@ -307,11 +302,10 @@ TEST_F(SecurityQueryTest, Parse_InvalidQuery) {
// some sample data
uint8_t raw_data[] = {0x6, 0x7, 0x8};
- const size_t raw_data_size =
- sizeof(raw_data)/sizeof(raw_data[0]);
+ const size_t raw_data_size = sizeof(raw_data) / sizeof(raw_data[0]);
const std::vector<uint8_t> vector =
- DeserializeData(invalid_query_header, raw_data, raw_data_size);
+ DeserializeData(invalid_query_header, raw_data, raw_data_size);
SecurityQuery query;
const bool result = query.SerializeQuery(&vector[0], vector.size());
@@ -320,9 +314,9 @@ TEST_F(SecurityQueryTest, Parse_InvalidQuery) {
EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), invalid_query_header);
ASSERT_EQ(query.get_data_size(), raw_data_size);
// query shall handle own array of byte data
- ASSERT_NE(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_NE(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
for (size_t i = 0; i < raw_data_size; ++i) {
- ASSERT_EQ(query.get_data()[i], raw_data[+ i]);
+ ASSERT_EQ(query.get_data()[i], raw_data[+i]);
}
// check side-effects
ASSERT_EQ(query.get_connection_key(), 0u);
@@ -344,7 +338,7 @@ TEST_F(SecurityQueryTest, Parse_InvalidQuery_UnknownTypeId) {
SEQ_NUMBER);
const std::vector<uint8_t> vector =
- DeserializeData(invalid_type_id_header, NULL, 0u);
+ DeserializeData(invalid_type_id_header, NULL, 0u);
SecurityQuery query;
const bool result = query.SerializeQuery(&vector[0], vector.size());
@@ -352,10 +346,11 @@ TEST_F(SecurityQueryTest, Parse_InvalidQuery_UnknownTypeId) {
// Parse set all unknown types and ids to INVALID_QUERY_ID
invalid_type_id_header.query_type = SecurityQuery::INVALID_QUERY_TYPE;
invalid_type_id_header.query_id = SecurityQuery::INVALID_QUERY_ID;
- EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), invalid_type_id_header);
+ EXPECT_PRED_FORMAT2(
+ QueryHeader_EQ, query.get_header(), invalid_type_id_header);
// check side-effects
ASSERT_EQ(query.get_data_size(), 0u);
- ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
ASSERT_EQ(query.get_connection_key(), 0u);
ASSERT_TRUE(query.get_json_message().empty());
}
@@ -370,7 +365,7 @@ TEST_F(SecurityQueryTest, Parse_InvalidQuery_UnknownId_Response) {
SecurityQuery::INVALID_QUERY_ID - 2,
SEQ_NUMBER);
const std::vector<uint8_t> vector =
- DeserializeData(invalid_id_header, NULL, 0u);
+ DeserializeData(invalid_id_header, NULL, 0u);
SecurityQuery query;
const bool result = query.SerializeQuery(&vector[0], vector.size());
@@ -380,7 +375,7 @@ TEST_F(SecurityQueryTest, Parse_InvalidQuery_UnknownId_Response) {
EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), invalid_id_header);
// check side-effects
ASSERT_EQ(query.get_data_size(), 0u);
- ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
ASSERT_EQ(query.get_connection_key(), 0u);
ASSERT_TRUE(query.get_json_message().empty());
}
@@ -395,11 +390,10 @@ TEST_F(SecurityQueryTest, Parse_Handshake) {
SEQ_NUMBER);
// some sample data
uint8_t raw_data[] = {0x6, 0x7, 0x8};
- const size_t raw_data_size =
- sizeof(raw_data)/sizeof(raw_data[0]);
+ const size_t raw_data_size = sizeof(raw_data) / sizeof(raw_data[0]);
const std::vector<uint8_t> vector =
- DeserializeData(handshake_header, raw_data, raw_data_size);
+ DeserializeData(handshake_header, raw_data, raw_data_size);
SecurityQuery query;
const bool result = query.SerializeQuery(&vector[0], vector.size());
@@ -407,9 +401,9 @@ TEST_F(SecurityQueryTest, Parse_Handshake) {
EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), handshake_header);
ASSERT_EQ(query.get_data_size(), raw_data_size);
// query shall handle own array of byte data
- ASSERT_NE(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_NE(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
for (size_t i = 0; i < raw_data_size; ++i) {
- ASSERT_EQ(query.get_data()[i], raw_data[+ i]);
+ ASSERT_EQ(query.get_data()[i], raw_data[+i]);
}
// check side-effects
ASSERT_EQ(query.get_connection_key(), 0u);
@@ -426,23 +420,22 @@ TEST_F(SecurityQueryTest, Parse_Handshake) {
TEST_F(SecurityQueryTest, Parse_InternalError) {
std::string error_str = "{some error}";
SecurityQuery::QueryHeader internal_error_header(
- SecurityQuery::REQUEST,
- SecurityQuery::SEND_INTERNAL_ERROR,
- SEQ_NUMBER);
+ SecurityQuery::REQUEST, SecurityQuery::SEND_INTERNAL_ERROR, SEQ_NUMBER);
internal_error_header.json_size = error_str.size();
const uint8_t* raw_data = reinterpret_cast<const uint8_t*>(error_str.c_str());
const std::vector<uint8_t> vector =
- DeserializeData(internal_error_header, raw_data, error_str.size());
+ DeserializeData(internal_error_header, raw_data, error_str.size());
SecurityQuery query;
const bool result = query.SerializeQuery(&vector[0], vector.size());
ASSERT_TRUE(result);
- EXPECT_PRED_FORMAT2(QueryHeader_EQ, query.get_header(), internal_error_header);
+ EXPECT_PRED_FORMAT2(
+ QueryHeader_EQ, query.get_header(), internal_error_header);
// check side-effects
ASSERT_EQ(query.get_data_size(), 0u);
- ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t *>(NULL));
+ ASSERT_EQ(query.get_data(), reinterpret_cast<uint8_t*>(NULL));
ASSERT_EQ(query.get_connection_key(), 0u);
ASSERT_EQ(query.get_json_message(), error_str);
@@ -451,6 +444,6 @@ TEST_F(SecurityQueryTest, Parse_InternalError) {
ASSERT_EQ(deserialize_vector, vector);
}
-} // namespace security_manager_test
-} // namespace components
-} // namespace test
+} // namespace security_manager_test
+} // namespace components
+} // namespace test
diff --git a/src/components/security_manager/test/ssl_certificate_handshake_test.cc b/src/components/security_manager/test/ssl_certificate_handshake_test.cc
new file mode 100644
index 0000000000..3d62dd5d6a
--- /dev/null
+++ b/src/components/security_manager/test/ssl_certificate_handshake_test.cc
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2015, 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 <fstream>
+#include <sstream>
+
+#include "gtest/gtest.h"
+#include "security_manager/crypto_manager_impl.h"
+#include "security_manager/mock_security_manager_settings.h"
+#include "utils/custom_string.h"
+
+using ::testing::Return;
+using ::testing::ReturnRef;
+
+namespace test {
+namespace components {
+namespace ssl_handshake_test {
+namespace custom_str = utils::custom_string;
+// Use this macro for correct line printing
+// in case of fail insize of the #method
+#define GTEST_TRACE(method) \
+ do { \
+ SCOPED_TRACE(""); \
+ method; \
+ } while (false)
+
+namespace {
+const std::string server_ca_cert_filename = "server";
+const std::string client_ca_cert_filename = "client";
+const std::string client_certificate = "client/client_credential.p12.enc";
+const std::string server_certificate = "server/spt_credential.p12.enc";
+const std::string server_unsigned_cert_file =
+ "server/spt_credential_unsigned.p12.enc";
+const std::string server_expired_cert_file =
+ "server/spt_credential_expired.p12.enc";
+
+const bool verify_peer = true;
+const bool skip_peer_verification = false;
+
+const size_t updates_before_hour = 24;
+
+} // namespace
+
+class SSLHandshakeTest : public testing::Test {
+ protected:
+ void SetUp() OVERRIDE {
+ mock_server_manager_settings = new testing::NiceMock<
+ security_manager_test::MockCryptoManagerSettings>();
+
+ server_manager = new security_manager::CryptoManagerImpl(
+ utils::SharedPtr<security_manager::CryptoManagerSettings>(
+ mock_server_manager_settings));
+ ASSERT_TRUE(server_manager);
+ mock_client_manager_settings = new testing::NiceMock<
+ security_manager_test::MockCryptoManagerSettings>();
+
+ client_manager = new security_manager::CryptoManagerImpl(
+ utils::SharedPtr<security_manager::CryptoManagerSettings>(
+ mock_client_manager_settings));
+ ASSERT_TRUE(client_manager);
+ server_ctx = NULL;
+ client_ctx = NULL;
+ }
+
+ void TearDown() OVERRIDE {
+ server_manager->ReleaseSSLContext(server_ctx);
+ delete server_manager;
+ client_manager->ReleaseSSLContext(client_ctx);
+ delete client_manager;
+ }
+
+ void SetServerInitialValues(const security_manager::Protocol protocol,
+ const std::string cert,
+ const std::string server_ciphers_list,
+ const bool verify_peer,
+ const std::string& ca_certificate_path) {
+ server_certificate_ = cert;
+ server_ciphers_list_ = server_ciphers_list;
+ server_ca_certificate_path_ = ca_certificate_path;
+
+ ON_CALL(*mock_server_manager_settings, security_manager_mode())
+ .WillByDefault(Return(security_manager::SERVER));
+ ON_CALL(*mock_server_manager_settings, security_manager_protocol_name())
+ .WillByDefault(Return(protocol));
+ ON_CALL(*mock_server_manager_settings, certificate_data())
+ .WillByDefault(ReturnRef(server_certificate_));
+ ON_CALL(*mock_server_manager_settings, ciphers_list())
+ .WillByDefault(ReturnRef(server_ciphers_list_));
+ ON_CALL(*mock_server_manager_settings, ca_cert_path())
+ .WillByDefault(ReturnRef(server_ca_certificate_path_));
+ ON_CALL(*mock_server_manager_settings, verify_peer())
+ .WillByDefault(Return(verify_peer));
+ }
+ void SetClientInitialValues(const security_manager::Protocol protocol,
+ const std::string certificate,
+ const std::string client_ciphers_list,
+ const bool verify_peer,
+ const std::string& ca_certificate_path) {
+ client_certificate_ = certificate;
+ client_ciphers_list_ = client_ciphers_list;
+ client_ca_certificate_path_ = ca_certificate_path;
+
+ ON_CALL(*mock_client_manager_settings, security_manager_mode())
+ .WillByDefault(Return(security_manager::CLIENT));
+ ON_CALL(*mock_client_manager_settings, security_manager_protocol_name())
+ .WillByDefault(Return(protocol));
+ ON_CALL(*mock_client_manager_settings, certificate_data())
+ .WillByDefault(ReturnRef(client_certificate_));
+ ON_CALL(*mock_client_manager_settings, ciphers_list())
+ .WillByDefault(ReturnRef(client_ciphers_list_));
+ ON_CALL(*mock_client_manager_settings, ca_cert_path())
+ .WillByDefault(ReturnRef(client_ca_certificate_path_));
+ ON_CALL(*mock_client_manager_settings, verify_peer())
+ .WillByDefault(Return(verify_peer));
+ }
+
+ bool InitServerManagers(security_manager::Protocol protocol,
+ const std::string& cert_filename,
+ const std::string& ciphers_list,
+ const bool verify_peer,
+ const std::string& ca_certificate_path) {
+ std::ifstream cert(cert_filename);
+ std::stringstream ss;
+ if (cert.is_open()) {
+ ss << cert.rdbuf();
+ }
+ cert.close();
+ SetServerInitialValues(
+ protocol, ss.str(), ciphers_list, verify_peer, ca_certificate_path);
+ const bool initialized = server_manager->Init();
+
+ if (!initialized) {
+ return false;
+ }
+
+ server_ctx = server_manager->CreateSSLContext();
+
+ if (!server_ctx) {
+ return false;
+ }
+
+ server_ctx->SetHandshakeContext(
+ security_manager::SSLContext::HandshakeContext(
+ custom_str::CustomString("SPT"),
+ custom_str::CustomString("client")));
+
+ return true;
+ }
+
+ bool InitClientManagers(security_manager::Protocol protocol,
+ const std::string& cert_filename,
+ const std::string& ciphers_list,
+ const bool verify_peer,
+ const std::string& ca_certificate_path) {
+ std::ifstream cert(cert_filename);
+ std::stringstream certificate;
+ if (cert.is_open()) {
+ certificate << cert.rdbuf();
+ }
+ cert.close();
+ SetClientInitialValues(protocol,
+ certificate.str(),
+ ciphers_list,
+ verify_peer,
+ ca_certificate_path);
+ const bool initialized = client_manager->Init();
+ if (!initialized) {
+ return false;
+ }
+
+ client_ctx = client_manager->CreateSSLContext();
+ if (!client_ctx) {
+ return false;
+ }
+
+ client_ctx->SetHandshakeContext(
+ security_manager::SSLContext::HandshakeContext(
+ custom_str::CustomString("SPT"),
+ custom_str::CustomString("server")));
+
+ return true;
+ }
+
+ void ResetConnections() {
+ ASSERT_NO_THROW(server_ctx->ResetConnection());
+ ASSERT_NO_THROW(client_ctx->ResetConnection());
+ }
+
+ void StartHandshake() {
+ using security_manager::SSLContext;
+
+ ASSERT_EQ(SSLContext::Handshake_Result_Success,
+ client_ctx->StartHandshake(&client_buf, &client_buf_len));
+ ASSERT_FALSE(client_buf == NULL);
+ ASSERT_GT(client_buf_len, 0u);
+ }
+
+ void HandshakeProcedure_Success() {
+ using security_manager::SSLContext;
+ StartHandshake();
+
+ while (true) {
+ ASSERT_EQ(SSLContext::Handshake_Result_Success,
+ server_ctx->DoHandshakeStep(
+ client_buf, client_buf_len, &server_buf, &server_buf_len))
+ << ERR_reason_error_string(ERR_get_error());
+ ASSERT_FALSE(server_buf == NULL);
+ ASSERT_GT(server_buf_len, 0u);
+
+ ASSERT_EQ(SSLContext::Handshake_Result_Success,
+ client_ctx->DoHandshakeStep(
+ server_buf, server_buf_len, &client_buf, &client_buf_len))
+ << ERR_reason_error_string(ERR_get_error());
+ if (server_ctx->IsInitCompleted()) {
+ break;
+ }
+
+ ASSERT_FALSE(client_buf == NULL);
+ ASSERT_GT(client_buf_len, 0u);
+ }
+ }
+
+ void HandshakeProcedure_ServerSideFail() {
+ using security_manager::SSLContext;
+
+ StartHandshake();
+
+ while (true) {
+ const SSLContext::HandshakeResult result = server_ctx->DoHandshakeStep(
+ client_buf, client_buf_len, &server_buf, &server_buf_len);
+ ASSERT_FALSE(server_ctx->IsInitCompleted())
+ << "Expected server side handshake fail";
+
+ // First few handshake will be successful
+ if (result != SSLContext::Handshake_Result_Success) {
+ // Test successfully passed with handshake fail
+ return;
+ }
+ ASSERT_FALSE(server_buf == NULL);
+ ASSERT_GT(server_buf_len, 0u);
+
+ ASSERT_EQ(SSLContext::Handshake_Result_Success,
+ client_ctx->DoHandshakeStep(
+ server_buf, server_buf_len, &client_buf, &client_buf_len))
+ << ERR_reason_error_string(ERR_get_error());
+ ASSERT_FALSE(client_ctx->IsInitCompleted())
+ << "Expected server side handshake fail";
+
+ ASSERT_FALSE(client_buf == NULL);
+ ASSERT_GT(client_buf_len, 0u);
+ }
+ FAIL() << "Expected server side handshake fail";
+ }
+
+ void HandshakeProcedure_ClientSideFail(
+ security_manager::SSLContext::HandshakeResult expected_result) {
+ using security_manager::SSLContext;
+
+ StartHandshake();
+
+ while (true) {
+ ASSERT_EQ(SSLContext::Handshake_Result_Success,
+ server_ctx->DoHandshakeStep(
+ client_buf, client_buf_len, &server_buf, &server_buf_len))
+ << ERR_reason_error_string(ERR_get_error());
+
+ ASSERT_FALSE(server_buf == NULL);
+ ASSERT_GT(server_buf_len, 0u);
+
+ const SSLContext::HandshakeResult result = client_ctx->DoHandshakeStep(
+ server_buf, server_buf_len, &client_buf, &client_buf_len);
+ ASSERT_FALSE(client_ctx->IsInitCompleted())
+ << "Expected client side handshake fail";
+
+ // First few handsahke will be successful
+ if (result != SSLContext::Handshake_Result_Success) {
+ // Test successfully passed with handshake fail
+ ASSERT_EQ(expected_result, result);
+ return;
+ }
+
+ ASSERT_FALSE(client_buf == NULL);
+ ASSERT_GT(client_buf_len, 0u);
+ }
+ FAIL() << "Expected client side handshake fail";
+ }
+
+ security_manager::CryptoManager* server_manager;
+ security_manager::CryptoManager* client_manager;
+ security_manager::SSLContext* server_ctx;
+ security_manager::SSLContext* client_ctx;
+ testing::NiceMock<security_manager_test::MockCryptoManagerSettings>*
+ mock_server_manager_settings;
+ testing::NiceMock<security_manager_test::MockCryptoManagerSettings>*
+ mock_client_manager_settings;
+
+ const uint8_t* server_buf;
+ const uint8_t* client_buf;
+ size_t server_buf_len;
+ size_t client_buf_len;
+
+ std::string server_certificate_;
+ std::string server_ciphers_list_;
+ std::string server_ca_certificate_path_;
+
+ std::string client_certificate_;
+ std::string client_ciphers_list_;
+ std::string client_ca_certificate_path_;
+};
+
+TEST_F(SSLHandshakeTest, NoVerification) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ skip_peer_verification,
+ ""))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ skip_peer_verification,
+ ""))
+ << client_manager->LastError();
+
+ GTEST_TRACE(HandshakeProcedure_Success());
+}
+
+TEST_F(SSLHandshakeTest, CAVerification_ServerSide) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ verify_peer,
+ client_ca_cert_filename))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ skip_peer_verification,
+ ""))
+ << client_manager->LastError();
+
+ GTEST_TRACE(HandshakeProcedure_Success());
+}
+
+TEST_F(SSLHandshakeTest, CAVerification_ServerSide_NoCACertificate) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ verify_peer,
+ "unex"))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ skip_peer_verification,
+ ""))
+ << client_manager->LastError();
+
+ GTEST_TRACE(HandshakeProcedure_ServerSideFail());
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ verify_peer,
+ client_ca_cert_filename))
+ << server_manager->LastError();
+
+ GTEST_TRACE(ResetConnections());
+
+ GTEST_TRACE(HandshakeProcedure_Success());
+}
+
+TEST_F(SSLHandshakeTest, CAVerification_ClientSide) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ verify_peer,
+ client_ca_cert_filename))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ verify_peer,
+ server_ca_cert_filename))
+ << client_manager->LastError();
+
+ GTEST_TRACE(HandshakeProcedure_Success());
+}
+
+TEST_F(SSLHandshakeTest, CAVerification_ClientSide_NoCACertificate) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ skip_peer_verification,
+ ""))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ verify_peer,
+ "client_ca_cert_filename"))
+ << client_manager->LastError();
+
+ GTEST_TRACE(HandshakeProcedure_ClientSideFail(
+ security_manager::SSLContext::Handshake_Result_Fail));
+
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ verify_peer,
+ server_ca_cert_filename))
+ << client_manager->LastError();
+
+ GTEST_TRACE(ResetConnections());
+
+ GTEST_TRACE(HandshakeProcedure_Success());
+}
+
+TEST_F(SSLHandshakeTest, CAVerification_BothSides) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ verify_peer,
+ client_ca_cert_filename))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ verify_peer,
+ server_ca_cert_filename))
+ << client_manager->LastError();
+
+ GTEST_TRACE(HandshakeProcedure_Success());
+}
+
+TEST_F(SSLHandshakeTest, UnsignedCert) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_unsigned_cert_file,
+ "ALL",
+ skip_peer_verification,
+ ""))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ verify_peer,
+ client_ca_cert_filename))
+ << client_manager->LastError();
+ GTEST_TRACE(HandshakeProcedure_ClientSideFail(
+ security_manager::SSLContext::Handshake_Result_CertNotSigned));
+}
+
+TEST_F(SSLHandshakeTest, ExpiredCert) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_expired_cert_file,
+ "ALL",
+ verify_peer,
+ client_ca_cert_filename))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ verify_peer,
+ server_ca_cert_filename))
+ << client_manager->LastError();
+
+ GTEST_TRACE(HandshakeProcedure_ClientSideFail(
+ security_manager::SSLContext::Handshake_Result_CertExpired));
+}
+
+TEST_F(SSLHandshakeTest, AppNameAndAppIDInvalid) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ verify_peer,
+ client_ca_cert_filename))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ verify_peer,
+ server_ca_cert_filename))
+ << client_manager->LastError();
+
+ client_ctx->SetHandshakeContext(
+ security_manager::SSLContext::HandshakeContext(
+ custom_str::CustomString("server"),
+ custom_str::CustomString("Wrong")));
+
+ GTEST_TRACE(HandshakeProcedure_ClientSideFail(
+ security_manager::SSLContext::Handshake_Result_AppNameMismatch));
+
+ ResetConnections();
+ client_ctx->SetHandshakeContext(
+ security_manager::SSLContext::HandshakeContext(
+ custom_str::CustomString("Wrong"),
+ custom_str::CustomString("server")));
+
+ GTEST_TRACE(HandshakeProcedure_ClientSideFail(
+ security_manager::SSLContext::Handshake_Result_AppIDMismatch));
+}
+
+TEST_F(SSLHandshakeTest, NoVerification_ResetConnection) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ skip_peer_verification,
+ ""))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ skip_peer_verification,
+ ""))
+ << client_manager->LastError();
+
+ const int times = 100;
+ for (int i = 0; i < times; ++i) {
+ // Expect success handshake
+ GTEST_TRACE(HandshakeProcedure_Success());
+
+ // Reset SSl connections
+ GTEST_TRACE(ResetConnections());
+ }
+}
+
+TEST_F(SSLHandshakeTest, CAVerification_BothSides_ResetConnection) {
+ ASSERT_TRUE(InitServerManagers(security_manager::TLSv1_2,
+ server_certificate,
+ "ALL",
+ verify_peer,
+ client_ca_cert_filename))
+ << server_manager->LastError();
+ ASSERT_TRUE(InitClientManagers(security_manager::TLSv1_2,
+ client_certificate,
+ "ALL",
+ skip_peer_verification,
+ server_ca_cert_filename))
+ << client_manager->LastError();
+
+ const int times = 100;
+ for (int i = 0; i < times; ++i) {
+ // Expect success handshake
+ GTEST_TRACE(HandshakeProcedure_Success());
+
+ // Reset SSl connections
+ GTEST_TRACE(ResetConnections());
+ }
+}
+
+// TODO(EZamakhov): add fail tests -broken or not full ca certificate chain
+
+} // namespace ssl_handshake_test
+} // namespace components
+} // namespace test
diff --git a/src/components/security_manager/test/ssl_context_test.cc b/src/components/security_manager/test/ssl_context_test.cc
new file mode 100644
index 0000000000..b35da3fc61
--- /dev/null
+++ b/src/components/security_manager/test/ssl_context_test.cc
@@ -0,0 +1,535 @@
+/*
+ * Copyright (c) 2016, 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 <fstream>
+#include <sstream>
+#include <string>
+#include <openssl/ssl.h>
+
+#include "security_manager/crypto_manager.h"
+#include "security_manager/crypto_manager_impl.h"
+#include "security_manager/ssl_context.h"
+#include "utils/custom_string.h"
+#include "security_manager/mock_security_manager_settings.h"
+#include "utils/shared_ptr.h"
+#include "utils/make_shared.h"
+
+using ::testing::Return;
+using ::testing::ReturnRef;
+using ::testing::NiceMock;
+
+namespace {
+const size_t kUpdatesBeforeHour = 24;
+const std::string kCaPath = "";
+const uint8_t* kServerBuf;
+const uint8_t* kClientBuf;
+const std::string kAllCiphers = "ALL";
+size_t server_buf_len;
+size_t client_buf_len;
+#ifdef __QNXNTO__
+const std::string kFordCipher = SSL3_TXT_RSA_DES_192_CBC3_SHA;
+#else
+// Used cipher from ford protocol requirement
+const std::string kFordCipher = TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384;
+#endif
+} // namespace
+
+namespace test {
+namespace components {
+namespace ssl_context_test {
+namespace custom_str = utils::custom_string;
+
+struct ProtocolAndCipher {
+ security_manager::Protocol server_protocol;
+ security_manager::Protocol client_protocol;
+ std::string server_ciphers_list;
+ std::string client_ciphers_list;
+
+ ProtocolAndCipher(security_manager::Protocol s_protocol,
+ security_manager::Protocol c_protocol,
+ std::string s_ciphers_list,
+ std::string c_ciphers_list)
+ : server_protocol(s_protocol)
+ , client_protocol(c_protocol)
+ , server_ciphers_list(s_ciphers_list)
+ , client_ciphers_list(c_ciphers_list) {}
+};
+
+class SSLTest : public testing::Test {
+ protected:
+ static void SetUpTestCase() {
+ std::ifstream certificate_file("server/spt_credential_unsigned.p12");
+ std::stringstream certificate;
+ if (certificate_file.is_open()) {
+ certificate << certificate_file.rdbuf();
+ }
+ certificate_file.close();
+ certificate_data_base64_ = certificate.str();
+ ASSERT_FALSE(certificate_data_base64_.empty())
+ << "Certificate data file is empty";
+ }
+
+ virtual void SetUp() OVERRIDE {
+ mock_crypto_manager_settings_ = utils::MakeShared<
+ NiceMock<security_manager_test::MockCryptoManagerSettings>>();
+ utils::SharedPtr<security_manager::CryptoManagerSettings> crypto_set(
+ mock_crypto_manager_settings_);
+ crypto_manager_ = new security_manager::CryptoManagerImpl(crypto_set);
+
+ EXPECT_CALL(*mock_crypto_manager_settings_, security_manager_mode())
+ .WillOnce(Return(security_manager::SERVER));
+ EXPECT_CALL(*mock_crypto_manager_settings_,
+ security_manager_protocol_name())
+ .WillOnce(Return(security_manager::TLSv1_2));
+ EXPECT_CALL(*mock_crypto_manager_settings_, certificate_data())
+ .WillOnce(ReturnRef(certificate_data_base64_));
+ EXPECT_CALL(*mock_crypto_manager_settings_, ciphers_list())
+ .WillRepeatedly(ReturnRef(kAllCiphers));
+ EXPECT_CALL(*mock_crypto_manager_settings_, ca_cert_path())
+ .WillRepeatedly(ReturnRef(kCaPath));
+ EXPECT_CALL(*mock_crypto_manager_settings_, verify_peer())
+ .WillOnce(Return(false));
+ const bool crypto_manager_initialization = crypto_manager_->Init();
+ EXPECT_TRUE(crypto_manager_initialization);
+
+ mock_client_manager_settings_ = utils::MakeShared<
+ NiceMock<security_manager_test::MockCryptoManagerSettings>>();
+ utils::SharedPtr<security_manager::CryptoManagerSettings> client_crypto(
+ mock_client_manager_settings_);
+ client_manager_ = new security_manager::CryptoManagerImpl(client_crypto);
+
+ EXPECT_CALL(*mock_client_manager_settings_, security_manager_mode())
+ .WillOnce(Return(security_manager::CLIENT));
+ EXPECT_CALL(*mock_client_manager_settings_,
+ security_manager_protocol_name())
+ .WillOnce(Return(security_manager::TLSv1_2));
+ EXPECT_CALL(*mock_client_manager_settings_, certificate_data())
+ .WillOnce(ReturnRef(certificate_data_base64_));
+ EXPECT_CALL(*mock_client_manager_settings_, ciphers_list())
+ .WillRepeatedly(ReturnRef(kAllCiphers));
+ EXPECT_CALL(*mock_client_manager_settings_, ca_cert_path())
+ .Times(2)
+ .WillRepeatedly(ReturnRef(kCaPath));
+ EXPECT_CALL(*mock_client_manager_settings_, verify_peer())
+ .WillOnce(Return(false));
+ const bool client_manager_initialization = client_manager_->Init();
+ EXPECT_TRUE(client_manager_initialization);
+
+ ON_CALL(*mock_crypto_manager_settings_, maximum_payload_size())
+ .WillByDefault(Return(kMaximumPayloadSize));
+ ON_CALL(*mock_client_manager_settings_, maximum_payload_size())
+ .WillByDefault(Return(kMaximumPayloadSize));
+ EXPECT_CALL(*mock_crypto_manager_settings_, security_manager_mode())
+ .WillRepeatedly(Return(security_manager::SERVER));
+ server_ctx = crypto_manager_->CreateSSLContext();
+ EXPECT_CALL(*mock_client_manager_settings_, security_manager_mode())
+ .Times(2)
+ .WillRepeatedly(Return(security_manager::CLIENT));
+ client_ctx = client_manager_->CreateSSLContext();
+
+ using custom_str::CustomString;
+ security_manager::SSLContext::HandshakeContext ctx(CustomString("SPT"),
+ CustomString("client"));
+ server_ctx->SetHandshakeContext(ctx);
+
+ ctx.expected_cn = "server";
+ client_ctx->SetHandshakeContext(ctx);
+
+ kServerBuf = NULL;
+ kClientBuf = NULL;
+ server_buf_len = 0u;
+ client_buf_len = 0u;
+ }
+
+ void TearDown() OVERRIDE {
+ crypto_manager_->ReleaseSSLContext(server_ctx);
+ client_manager_->ReleaseSSLContext(client_ctx);
+
+ delete crypto_manager_;
+ delete client_manager_;
+ }
+
+ const size_t kMaximumPayloadSize = 1000u;
+ security_manager::CryptoManager* crypto_manager_;
+ security_manager::CryptoManager* client_manager_;
+ utils::SharedPtr<NiceMock<security_manager_test::MockCryptoManagerSettings>>
+ mock_crypto_manager_settings_;
+ utils::SharedPtr<NiceMock<security_manager_test::MockCryptoManagerSettings>>
+ mock_client_manager_settings_;
+ security_manager::SSLContext* server_ctx;
+ security_manager::SSLContext* client_ctx;
+
+ static std::string certificate_data_base64_;
+};
+std::string SSLTest::certificate_data_base64_;
+
+// StartHandshake() fails when client and server protocols are not TLSv1_2
+class SSLTestParam : public testing::TestWithParam<ProtocolAndCipher> {
+ protected:
+ virtual void SetUp() OVERRIDE {
+ std::ifstream certificate_file("server/spt_credential.p12");
+ ASSERT_TRUE(certificate_file.is_open())
+ << "Could not open certificate data file";
+
+ const std::string certificate(
+ (std::istreambuf_iterator<char>(certificate_file)),
+ std::istreambuf_iterator<char>());
+ certificate_file.close();
+ ASSERT_FALSE(certificate.empty()) << "Certificate data file is empty";
+ certificate_data_base64_ = certificate;
+
+ mock_crypto_manager_settings_ = utils::MakeShared<
+ NiceMock<security_manager_test::MockCryptoManagerSettings>>();
+ utils::SharedPtr<security_manager::CryptoManagerSettings> server_crypto(
+ mock_crypto_manager_settings_);
+ crypto_manager = new security_manager::CryptoManagerImpl(server_crypto);
+
+ SetServerInitialValues(GetParam().server_protocol,
+ GetParam().server_ciphers_list);
+
+ const bool crypto_manager_initialization = crypto_manager->Init();
+ EXPECT_TRUE(crypto_manager_initialization);
+
+ mock_client_manager_settings_ = utils::MakeShared<
+ NiceMock<security_manager_test::MockCryptoManagerSettings>>();
+
+ utils::SharedPtr<security_manager::CryptoManagerSettings> client_crypto(
+ mock_client_manager_settings_);
+ client_manager = new security_manager::CryptoManagerImpl(client_crypto);
+
+ SetClientInitialValues(GetParam().client_protocol,
+ GetParam().client_ciphers_list);
+
+ const bool client_manager_initialization = client_manager->Init();
+ EXPECT_TRUE(client_manager_initialization);
+
+ server_ctx = crypto_manager->CreateSSLContext();
+ client_ctx = client_manager->CreateSSLContext();
+
+ using custom_str::CustomString;
+ security_manager::SSLContext::HandshakeContext ctx(CustomString("SPT"),
+ CustomString("client"));
+ server_ctx->SetHandshakeContext(ctx);
+
+ ctx.expected_cn = "server";
+ client_ctx->SetHandshakeContext(ctx);
+
+ kServerBuf = NULL;
+ kClientBuf = NULL;
+ server_buf_len = 0u;
+ client_buf_len = 0u;
+ }
+
+ void TearDown() OVERRIDE {
+ crypto_manager->ReleaseSSLContext(server_ctx);
+ client_manager->ReleaseSSLContext(client_ctx);
+
+ delete crypto_manager;
+ delete client_manager;
+ }
+
+ void SetServerInitialValues(security_manager::Protocol protocol,
+ const std::string& server_ciphers_list) {
+ ON_CALL(*mock_crypto_manager_settings_, security_manager_mode())
+ .WillByDefault(Return(security_manager::SERVER));
+ ON_CALL(*mock_crypto_manager_settings_, security_manager_protocol_name())
+ .WillByDefault(Return(protocol));
+ ON_CALL(*mock_crypto_manager_settings_, certificate_data())
+ .WillByDefault(ReturnRef(certificate_data_base64_));
+ ON_CALL(*mock_crypto_manager_settings_, ciphers_list())
+ .WillByDefault(ReturnRef(server_ciphers_list));
+ ON_CALL(*mock_crypto_manager_settings_, ca_cert_path())
+ .WillByDefault(ReturnRef(kCaPath));
+ ON_CALL(*mock_crypto_manager_settings_, verify_peer())
+ .WillByDefault(Return(false));
+ }
+ void SetClientInitialValues(security_manager::Protocol protocol,
+ const std::string& client_ciphers_list) {
+ ON_CALL(*mock_client_manager_settings_, security_manager_mode())
+ .WillByDefault(Return(security_manager::CLIENT));
+ ON_CALL(*mock_client_manager_settings_, security_manager_protocol_name())
+ .WillByDefault(Return(protocol));
+ ON_CALL(*mock_client_manager_settings_, certificate_data())
+ .WillByDefault(ReturnRef(certificate_data_base64_));
+ ON_CALL(*mock_client_manager_settings_, ciphers_list())
+ .WillByDefault(ReturnRef(client_ciphers_list));
+ ON_CALL(*mock_client_manager_settings_, ca_cert_path())
+ .WillByDefault(ReturnRef(kCaPath));
+ ON_CALL(*mock_client_manager_settings_, verify_peer())
+ .WillByDefault(Return(false));
+ }
+
+ utils::SharedPtr<NiceMock<security_manager_test::MockCryptoManagerSettings>>
+ mock_crypto_manager_settings_;
+ utils::SharedPtr<NiceMock<security_manager_test::MockCryptoManagerSettings>>
+ mock_client_manager_settings_;
+ security_manager::CryptoManager* crypto_manager;
+ security_manager::CryptoManager* client_manager;
+ security_manager::SSLContext* server_ctx;
+ security_manager::SSLContext* client_ctx;
+ std::string certificate_data_base64_;
+};
+
+class SSLTestForTLS1_2 : public SSLTestParam {};
+
+// This case fails starting because we can handshake only with TLSv1_2 protocol.
+INSTANTIATE_TEST_CASE_P(
+ CorrectProtocolAndCiphers,
+ SSLTestParam,
+ ::testing::Values(ProtocolAndCipher(security_manager::TLSv1,
+ security_manager::TLSv1,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::TLSv1_1,
+ security_manager::TLSv1_1,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::SSLv3,
+ security_manager::SSLv3,
+ kFordCipher,
+ kFordCipher)));
+
+INSTANTIATE_TEST_CASE_P(
+ IncorrectProtocolAndCiphers,
+ SSLTestParam,
+ ::testing::Values(ProtocolAndCipher(security_manager::TLSv1,
+ security_manager::TLSv1_1,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::TLSv1,
+ security_manager::SSLv3,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::TLSv1_1,
+ security_manager::TLSv1,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::TLSv1_1,
+ security_manager::SSLv3,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::TLSv1_2,
+ security_manager::TLSv1,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::TLSv1_2,
+ security_manager::TLSv1_1,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::TLSv1_2,
+ security_manager::SSLv3,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::SSLv3,
+ security_manager::TLSv1,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::SSLv3,
+ security_manager::TLSv1_1,
+ kFordCipher,
+ kFordCipher)));
+
+TEST_F(SSLTest, OnTSL2Protocol_BrokenHandshake) {
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
+ client_ctx->StartHandshake(&kClientBuf, &client_buf_len));
+ ASSERT_FALSE(NULL == kClientBuf);
+ ASSERT_LT(0u, client_buf_len);
+ // Broke 3 bytes for get abnormal fail of handshake
+ const_cast<uint8_t*>(kClientBuf)[0] ^= 0xFF;
+ const_cast<uint8_t*>(kClientBuf)[client_buf_len / 2] ^= 0xFF;
+ const_cast<uint8_t*>(kClientBuf)[client_buf_len - 1] ^= 0xFF;
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_AbnormalFail,
+ server_ctx->DoHandshakeStep(
+ kClientBuf, client_buf_len, &kServerBuf, &server_buf_len));
+ EXPECT_EQ("Initialization is not completed", server_ctx->LastError());
+ EXPECT_EQ("Initialization is not completed", client_ctx->LastError());
+}
+
+// TODO {AKozoriz} : Unexpected uncomplited init of SSL component.
+// In this and next tests.
+// Must be fixed after merge to develop.
+TEST_F(SSLTest, DISABLED_OnTSL2Protocol_Positive) {
+ ASSERT_EQ(client_ctx->StartHandshake(&kClientBuf, &client_buf_len),
+ security_manager::SSLContext::Handshake_Result_Success);
+ ASSERT_FALSE(NULL == kClientBuf);
+ ASSERT_LT(0u, client_buf_len);
+ EXPECT_TRUE(server_ctx->IsInitCompleted());
+
+ while (true) {
+ const security_manager::SSLContext::HandshakeResult server_result =
+ server_ctx->DoHandshakeStep(
+ kClientBuf, client_buf_len, &kServerBuf, &server_buf_len);
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
+ server_result);
+ ASSERT_FALSE(NULL == kServerBuf);
+ ASSERT_LT(0u, server_buf_len);
+
+ const security_manager::SSLContext::HandshakeResult client_result =
+ client_ctx->DoHandshakeStep(
+ kServerBuf, server_buf_len, &kClientBuf, &client_buf_len);
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
+ client_result);
+ if (server_ctx->IsInitCompleted()) {
+ break;
+ }
+
+ ASSERT_FALSE(NULL == kClientBuf);
+ ASSERT_LT(0u, client_buf_len);
+ }
+ // Expect empty buffers after init complete
+ ASSERT_TRUE(NULL == kClientBuf);
+ ASSERT_EQ(0u, client_buf_len);
+ // expect both side initialization complete
+ EXPECT_TRUE(client_ctx->IsInitCompleted());
+ EXPECT_TRUE(server_ctx->IsInitCompleted());
+
+ // Encrypt text on client side
+ const uint8_t* text = reinterpret_cast<const uint8_t*>("abra");
+ const uint8_t* encrypted_text = 0;
+ size_t text_len = 4;
+ size_t encrypted_text_len;
+ EXPECT_TRUE(client_ctx->Encrypt(
+ text, text_len, &encrypted_text, &encrypted_text_len));
+
+ ASSERT_NE(reinterpret_cast<void*>(NULL), encrypted_text);
+ ASSERT_LT(0u, encrypted_text_len);
+
+ // Decrypt text on server side
+ EXPECT_TRUE(server_ctx->Decrypt(
+ encrypted_text, encrypted_text_len, &text, &text_len));
+ ASSERT_NE(reinterpret_cast<void*>(NULL), text);
+ ASSERT_LT(0u, text_len);
+
+ ASSERT_EQ(strncmp(reinterpret_cast<const char*>(text), "abra", 4), 0);
+}
+
+TEST_F(SSLTest, DISABLED_OnTSL2Protocol_EcncryptionFail) {
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
+ client_ctx->StartHandshake(&kClientBuf, &client_buf_len));
+
+ while (!server_ctx->IsInitCompleted()) {
+ ASSERT_FALSE(NULL == kClientBuf);
+ ASSERT_LT(0u, client_buf_len);
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
+ server_ctx->DoHandshakeStep(
+ kClientBuf, client_buf_len, &kServerBuf, &server_buf_len));
+ ASSERT_FALSE(NULL == kServerBuf);
+ ASSERT_LT(0u, server_buf_len);
+
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
+ client_ctx->DoHandshakeStep(
+ kServerBuf, server_buf_len, &kClientBuf, &client_buf_len));
+ }
+ // Expect empty buffers after init complete
+ ASSERT_TRUE(NULL == kClientBuf);
+ ASSERT_EQ(0u, client_buf_len);
+ // Expect both side initialization complete
+ EXPECT_TRUE(client_ctx->IsInitCompleted());
+ EXPECT_TRUE(server_ctx->IsInitCompleted());
+
+ // Encrypt text on client side
+ const uint8_t* text = reinterpret_cast<const uint8_t*>("abra");
+ const uint8_t* encrypted_text = 0;
+ size_t text_len = 4;
+ size_t encrypted_text_len;
+ EXPECT_TRUE(client_ctx->Encrypt(
+ text, text_len, &encrypted_text, &encrypted_text_len));
+ ASSERT_NE(reinterpret_cast<void*>(NULL), encrypted_text);
+ ASSERT_LT(0u, encrypted_text_len);
+
+ std::vector<uint8_t> broken(encrypted_text,
+ encrypted_text + encrypted_text_len);
+ // Broke message
+ broken[encrypted_text_len / 2] ^= 0xFF;
+
+ const uint8_t* out_text;
+ size_t out_text_size;
+ // Decrypt broken text on server side
+ EXPECT_FALSE(server_ctx->Decrypt(
+ &broken[0], broken.size(), &out_text, &out_text_size));
+
+ // Check after broken message that server encryption and decryption fail
+ // Encrypte message on server side
+ EXPECT_FALSE(server_ctx->Decrypt(
+ encrypted_text, encrypted_text_len, &out_text, &out_text_size));
+ EXPECT_FALSE(server_ctx->Encrypt(
+ text, text_len, &encrypted_text, &encrypted_text_len));
+}
+
+TEST_P(SSLTestParam, ClientAndServerNotTLSv1_2_HandshakeFailed) {
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_AbnormalFail,
+ client_ctx->StartHandshake(&kClientBuf, &client_buf_len));
+ EXPECT_TRUE(NULL == kClientBuf);
+ EXPECT_EQ(0u, client_buf_len);
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
+ server_ctx->DoHandshakeStep(
+ kClientBuf, client_buf_len, &kServerBuf, &server_buf_len));
+ EXPECT_TRUE(NULL == kServerBuf);
+ EXPECT_EQ(0u, server_buf_len);
+
+ EXPECT_FALSE(server_ctx->IsInitCompleted());
+}
+
+INSTANTIATE_TEST_CASE_P(
+ ServerProtocolTLSv12,
+ SSLTestForTLS1_2,
+ ::testing::Values(ProtocolAndCipher(security_manager::TLSv1,
+ security_manager::TLSv1_2,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::TLSv1_1,
+ security_manager::TLSv1_2,
+ kFordCipher,
+ kFordCipher),
+ ProtocolAndCipher(security_manager::SSLv3,
+ security_manager::TLSv1_2,
+ kFordCipher,
+ kFordCipher)));
+
+TEST_P(SSLTestForTLS1_2, HandshakeFailed) {
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_Success,
+ client_ctx->StartHandshake(&kClientBuf, &client_buf_len));
+ EXPECT_FALSE(NULL == kClientBuf);
+ ASSERT_LT(0u, client_buf_len);
+ ASSERT_EQ(security_manager::SSLContext::Handshake_Result_AbnormalFail,
+ server_ctx->DoHandshakeStep(
+ kClientBuf, client_buf_len, &kServerBuf, &server_buf_len));
+ EXPECT_TRUE(NULL == kServerBuf);
+ EXPECT_EQ(0u, server_buf_len);
+
+ EXPECT_FALSE(server_ctx->IsInitCompleted());
+}
+
+} // namespace ssl_context_test
+} // namespace components
+} // namespace test