CVE-2023-50257: Improper Access Control (CWE-284)
value: eProsima Fast DDS (formerly Fast RTPS) is a C++ implementation of the Data Distribution Service standard of the Object Management Group. Even with the application of SROS2, due to the issue where the data (`p[UD]`) and `guid` values used to disconnect between nodes are not encrypted, a vulnerability has been discovered where a malicious attacker can forcibly disconnect a Subscriber and can deny a Subscriber attempting to connect. Afterwards, if the attacker sends the packet for disconnecting, which is data (`p[UD]`), to the Global Data Space (`239.255.0.1:7400`) using the said Publisher ID, all the Subscribers (Listeners) connected to the Publisher (Talker) will not receive any data and their connection will be disconnected. Moreover, if this disconnection packet is sent continuously, the Subscribers (Listeners) trying to connect will not be able to do so. Since the initial commit of the `SecurityManager.cpp` code (`init`, `on_process_handshake`) on Nov 8, 2016, the Disconnect Vulnerability in RTPS Packets Used by SROS2 has been present prior to versions 2.13.0, 2.12.2, 2.11.3, 2.10.3, and 2.6.7.
CWE description: The product does not restrict or incorrectly restricts access to a resource from an unauthorized actor.
Published: 2024-02-19T20:15Z
Repository: https://github.com/eProsima/Fast-DDS
Language: C
Files changed: include/fastrtps/rtps/security/authentication/Authentication.h, include/fastrtps/rtps/writer/ReaderProxy.h, src/cpp/CMakeLists.txt, src/cpp/rtps/participant/RTPSParticipantImpl.cpp, src/cpp/rtps/participant/RTPSParticipantImpl.h, src/cpp/rtps/security/SecurityManager.cpp, src/cpp/rtps/security/SecurityManager.h, src/cpp/security/authentication/PKIDH.cpp, src/cpp/security/authentication/PKIDH.h, test/CMakeLists.txt, test/mock/rtps/RTPSParticipantImpl/rtps/participant/RTPSParticipantImpl.h, test/mock/rtps/RTPSReader/fastrtps/rtps/reader/RTPSReader.h, test/mock/rtps/RTPSWriter/fastrtps/rtps/writer/RTPSWriter.h, test/mock/rtps/ReaderHistory/fastrtps/rtps/history/ReaderHistory.h, test/mock/rtps/SecurityPluginFactory/MockAuthenticationPlugin.h, test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.cpp, test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.h, test/mock/rtps/StatelessReader/fastrtps/rtps/reader/StatelessReader.h, test/mock/rtps/StatelessWriter/fastrtps/rtps/writer/StatelessWriter.h, test/mock/rtps/WriterHistory/fastrtps/rtps/history/WriterHistory.h, test/unittest/rtps/security/CMakeLists.txt, test/unittest/rtps/security/SecurityAuthenticationTests.cpp, test/unittest/security/authentication/BuiltinPKIDHTests.cpp
Commit date: 2016-11-08 15:32:00 +0100
Commit message: Refs #1811. WIP SecurityManager.

Diff: diff --git a/include/fastrtps/rtps/security/authentication/Authentication.h b/include/fastrtps/rtps/security/authentication/Authentication.h
index 427fa61f..835ae38f 100644
--- a/include/fastrtps/rtps/security/authentication/Authentication.h
+++ b/include/fastrtps/rtps/security/authentication/Authentication.h
@@ -92,11 +92,11 @@ class Authentication
          * @result Validation status.
          */
         virtual ValidationResult_t validate_remote_identity(IdentityHandle** remote_identity_handle,
                 const IdentityHandle& local_identity_handle,
                 IdentityToken&& remote_identity_token,
-                const GUID_t remote_participant_key,
+                const GUID_t& remote_participant_key,
                 SecurityException& exception) = 0;
 
         /*!
          * @brief This operation is used to initiate a handshake.
          * @param handshake_handle (out) A handle returned by the Authentication plugin used to keep the state of the
diff --git a/include/fastrtps/rtps/writer/ReaderProxy.h b/include/fastrtps/rtps/writer/ReaderProxy.h
index 020d79b2..d844a6b5 100644
--- a/include/fastrtps/rtps/writer/ReaderProxy.h
+++ b/include/fastrtps/rtps/writer/ReaderProxy.h
@@ -26,11 +26,10 @@
 #include "../common/CacheChange.h"
 #include "../common/FragmentNumber.h"
 #include "../attributes/WriterAttributes.h"
 
 #include <set>
-#include <unordered_map>
 
 namespace boost
 {
     class recursive_mutex;
 }
diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt
index b69778fe..4ac00808 100644
--- a/src/cpp/CMakeLists.txt
+++ b/src/cpp/CMakeLists.txt
@@ -168,16 +168,18 @@ if(MSVC OR MSVC_IDE)
         target_compile_definitions(${PROJECT_NAME}_static PUBLIC BOOST_ALL_DYN_LINK)
 
         # Define public headers
         target_include_directories(${PROJECT_NAME} PUBLIC
             $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/${PROJECT_NAME}>
+            $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/cpp>
             $<INSTALL_INTERFACE:include>
             )
 
         # Define public headers for static library
         target_include_directories(${PROJECT_NAME}_static PUBLIC
             $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/${PROJECT_NAME}>
+            $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/cpp>
             $<INSTALL_INTERFACE:include>
             )
 
         # Made linked libraries PRIVATE to prevent local directories in Windows installer.
         set(PRIVACY "")
@@ -199,10 +201,11 @@ else()
     add_library(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SOURCES})
 
     # Define public headers
     target_include_directories(${PROJECT_NAME} PUBLIC
         $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/${PROJECT_NAME}>
+        $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/cpp>
         $<INSTALL_INTERFACE:include>
         )
 
     # Link library to external libraries.
     target_link_libraries(${PROJECT_NAME}
diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp
index f8c67d0f..ab7a50df 100644
--- a/src/cpp/rtps/participant/RTPSParticipantImpl.cpp
+++ b/src/cpp/rtps/participant/RTPSParticipantImpl.cpp
@@ -85,11 +85,11 @@ Locator_t RTPSParticipantImpl::applyLocatorAdaptRule(Locator_t loc)
 }
 
 RTPSParticipantImpl::RTPSParticipantImpl(const RTPSParticipantAttributes& PParam,
         const GuidPrefix_t& guidP,
         RTPSParticipant* par,
-        RTPSParticipantListener* plisten):	m_att(PParam), m_guid(guidP,c_EntityId_RTPSParticipant),
+        RTPSParticipantListener* plisten):	m_att(PParam), m_guid(guidP ,c_EntityId_RTPSParticipant),
     mp_event_thr(nullptr),
     mp_builtinProtocols(nullptr),
     mp_ResourceSemaphore(new boost::interprocess::interprocess_semaphore(0)),
     IdCounter(0),
     mp_participantListener(plisten),
@@ -857,15 +857,10 @@ void RTPSParticipantImpl::ResourceSemaphoreWait()
 void RTPSParticipantImpl::assertRemoteRTPSParticipantLiveliness(const GuidPrefix_t& guidP)
 {
     this->mp_builtinProtocols->mp_PDP->assertRemoteParticipantLiveliness(guidP);
 }
 
-const RTPSParticipantAttributes& RTPSParticipantImpl::getRTPSParticipantAttributes() const
-{
-    return this->m_att;
-}
-
 uint32_t RTPSParticipantImpl::getMaxMessageSize() const
 {
     uint32_t minMaxMessageSize = UINT32_MAX;
     if(m_att.useBuiltinTransports)
     {
diff --git a/src/cpp/rtps/participant/RTPSParticipantImpl.h b/src/cpp/rtps/participant/RTPSParticipantImpl.h
index 8244c91a..95d76bca 100644
--- a/src/cpp/rtps/participant/RTPSParticipantImpl.h
+++ b/src/cpp/rtps/participant/RTPSParticipantImpl.h
@@ -11,11 +11,11 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
 /**
- * @file RTPSParticipant.h
+ * @file RTPSParticipantImpl.h
  */
 
 #ifndef RTPSParticipantIMPL_H_
 #define RTPSParticipantIMPL_H_
 #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
@@ -129,11 +129,13 @@ class RTPSParticipantImpl
 
         /**
          * Get associated GUID
          * @return Associated GUID
          */
-        inline const GUID_t& getGuid() const {return m_guid;};
+        inline const GUID_t& getGuid() const { return m_guid; }
+
+        void setGuid(GUID_t& guid) { m_guid = guid; }
 
         //! Announce RTPSParticipantState (force the sending of a DPD message.)
         void announceRTPSParticipantState();
         //!Stop the RTPSParticipant Announcement (used in tests to avoid multiple packets being send)
         void stopRTPSParticipantAnnouncement();
@@ -206,11 +208,11 @@ class RTPSParticipantImpl
 
     private:
         //!Attributes of the RTPSParticipant
         RTPSParticipantAttributes m_att;
         //!Guid of the RTPSParticipant.
-        const GUID_t m_guid;
+        GUID_t m_guid;
         //! Sending resources. - DEPRECATED -Stays commented for reference purposes
         // ResourceSend* mp_send_thr;
         //! Event Resource
         ResourceEvent* mp_event_thr;
         //! BuiltinProtocols of this RTPSParticipant
@@ -302,11 +304,14 @@ class RTPSParticipantImpl
          */
         std::vector<std::unique_ptr<FlowController> > m_controllers;
 
     public:
 
-        const RTPSParticipantAttributes& getRTPSParticipantAttributes() const;
+        const RTPSParticipantAttributes& getRTPSParticipantAttributes() const
+        {
+            return this->m_att;
+        }
 
         /**
          * Create a Writer in this RTPSParticipant.
          * @param Writer Pointer to pointer of the Writer, used as output. Only valid if return==true.
          * @param param WriterAttributes to define the Writer.
diff --git a/src/cpp/rtps/security/SecurityManager.cpp b/src/cpp/rtps/security/SecurityManager.cpp
index 47c38bff..d112a630 100644
--- a/src/cpp/rtps/security/SecurityManager.cpp
+++ b/src/cpp/rtps/security/SecurityManager.cpp
@@ -1,9 +1,392 @@
 #include "SecurityManager.h"
 
 #include <fastrtps/rtps/security/authentication/Authentication.h>
+#include <fastrtps/log/Log.h>
+#include <rtps/participant/RTPSParticipantImpl.h>
 
-using namespace eprosima::fastrtps::rtps::security;
+#include <fastrtps/rtps/writer/StatelessWriter.h>
+#include <fastrtps/rtps/reader/StatelessReader.h>
+#include <fastrtps/rtps/history/WriterHistory.h>
+#include <fastrtps/rtps/history/ReaderHistory.h>
+#include <fastrtps/rtps/attributes/HistoryAttributes.h>
 
-SecurityManager::SecurityManager()
+#include <cassert>
+#include <thread>
+
+#define ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_WRITER  0x000201C2
+#define ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_READER  0x000201C7
+
+const EntityId_t participant_stateless_message_writer_entity_id = ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_WRITER;
+const EntityId_t participant_stateless_message_reader_entity_id = ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_READER;
+
+using namespace eprosima::fastrtps;
+using namespace ::rtps;
+using namespace ::security;
+
+bool usleep_bool()
+{
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    return true;
+}
+
+SecurityManager::SecurityManager(RTPSParticipantImpl *participant) : participant_(participant),
+    participant_stateless_message_writer_(nullptr),
+    participant_stateless_message_writer_history_(nullptr),
+    participant_stateless_message_reader_(nullptr),
+    participant_stateless_message_reader_history_(nullptr),
+    authentication_plugin_(nullptr)
+{
+    assert(participant != nullptr);
+}
+
+SecurityManager::~SecurityManager()
+{
+    if(authentication_plugin_ != nullptr)
+        delete authentication_plugin_;
+}
+
+bool SecurityManager::init()
+{
+    SecurityException exception;
+
+    authentication_plugin_ = factory_.create_authentication_plugin(participant_->getRTPSParticipantAttributes().properties);
+
+    if(authentication_plugin_ != nullptr)
+    {
+        // Validate local participant
+        GUID_t adjusted_participant_key;
+        ValidationResult_t ret = VALIDATION_FAILED;
+        
+        do
+        {
+            ret = authentication_plugin_->validate_local_identity(&local_identity_handle_,
+                adjusted_participant_key,
+                participant_->getRTPSParticipantAttributes().builtin.domainId,
+                participant_->getRTPSParticipantAttributes(),
+                participant_->getGuid(),
+                exception);
+        } while(ret == VALIDATION_PENDING_RETRY && usleep_bool());
+
+        if(ret == VALIDATION_OK)
+        {
+            assert(local_identity_handle_ != nullptr);
+
+            // Create RTPS entities
+            if(create_entities())
+            {
+                return true;
+            }
+        }
+
+        delete authentication_plugin_;
+        authentication_plugin_ = nullptr;
+    }
+    else
+    {
+        logInfo(SECURITY, "Authentication plugin not configured. Security will be disable");
+    }
+
+    return false;
+}
+
+void SecurityManager::remove_discovered_participant_info(const GUID_t remote_participant_key)
+{
+    std::unique_lock<std::mutex> lock(mutex_);
+    auto dp_it = discovered_participants_.find(remote_participant_key);
+
+    if(dp_it != discovered_participants_.end())
+    {
+        IdentityHandle* identity_handle = dp_it->second.get_identity_handle();
+
+        if(identity_handle != nullptr)
+        {
+            SecurityException exception;
+            authentication_plugin_->return_identity_handle(identity_handle, exception);
+        }
+
+        discovered_participants_.erase(dp_it);
+    }
+}
+
+void SecurityManager::restore_remote_identity_handle(const GUID_t& remote_participant_key,
+        IdentityHandle* remote_identity_handle)
+{
+    SecurityException exception;
+
+    std::unique_lock<std::mutex> lock(mutex_);
+    auto dp_it = discovered_participants_.find(remote_participant_key);
+
+    if(dp_it != discovered_participants_.end())
+    {
+        assert(dp_it->second.is_identity_handle_null());
+        dp_it->second.set_identity_handle(remote_identity_handle);
+    }
+    else
+        authentication_plugin_->return_identity_handle(remote_identity_handle, exception);
+}
+
+bool SecurityManager::discovered_participant(IdentityToken&& remote_identity_token,
+        const GUID_t& remote_participant_key)
 {
+    IdentityHandle* remote_identity_handle = nullptr;
+    SecurityException exception;
+    AuthenticationStatus auth_status = AUTHENTICATION_INIT;
+
+    // Find information
+    mutex_.lock();
+    auto dp_it = discovered_participants_.find(remote_participant_key);
+
+    if(dp_it == discovered_participants_.end())
+    {
+        discovered_participants_.emplace(remote_participant_key, auth_status);
+
+        mutex_.unlock();
+
+        // Validate remote participant.
+        ValidationResult_t validation_ret = authentication_plugin_->validate_remote_identity(&remote_identity_handle,
+                *local_identity_handle_, std::move(remote_identity_token),
+                remote_participant_key, exception);
+
+        switch(validation_ret)
+        {
+            case VALIDATION_OK:
+                assert(remote_identity_handle != nullptr);
+                auth_status = AUTHENTICATION_OK;
+                break;
+            case VALIDATION_PENDING_HANDSHAKE_REQUEST:
+                assert(remote_identity_handle != nullptr);
+                auth_status = AUTHENTICATION_REQUEST_NOT_SEND;
+                break;
+            case VALIDATION_PENDING_HANDSHAKE_MESSAGE:
+                assert(remote_identity_handle != nullptr);
+                auth_status = AUTHENTICATION_WAITING_REQUEST;
+                break;
+            case VALIDATION_PENDING_RETRY:
+                // TODO(Ricardo) Send event.
+            default:
+                remove_discovered_participant_info(remote_participant_key);
+                return false;
+        };
+
+        // Store remote handle.
+        mutex_.lock();
+        dp_it = discovered_participants_.find(remote_participant_key);
+        if(dp_it != discovered_participants_.end())
+        {
+            dp_it->second.set_auth_status(auth_status);
+            bool ret = dp_it->second.set_identity_handle(remote_identity_handle);
+            (void)ret; assert(ret);
+            remote_identity_handle = nullptr;
+        }
+        else
+        {
+            mutex_.unlock();
+            authentication_plugin_->return_identity_handle(remote_identity_handle, exception); // TODO(Ricardo) Check error.
+            return false;
+        }
+    }
+    else
+    {
+        auth_status = dp_it->second.get_auth_status();
+
+        if(auth_status == AUTHENTICATION_INIT)
+            return false;
+    }
+
+    if(auth_status == AUTHENTICATION_REQUEST_NOT_SEND)
+    {
+        remote_identity_handle = dp_it->second.get_identity_handle();
+        assert(remote_identity_handle);
+    }
+    mutex_.unlock();
+
+    bool returnedValue = true;
+
+    // Maybe send request.
+    if(remote_identity_handle != nullptr)
+    {
+        returnedValue = on_request_not_send(remote_participant_key, remote_identity_handle);
+    }
+
+    return returnedValue;
+}
+
+bool SecurityManager::on_request_not_send(const GUID_t& remote_participant_key,
+        IdentityHandle* remote_identity_handle)
+{
+    assert(remote_identity_handle);
+
+    HandshakeHandle* handshake_handle = nullptr;
+    HandshakeMessageToken* handshake_message = nullptr;
+    SecurityException exception;
+    
+    ValidationResult_t ret = authentication_plugin_->begin_handshake_request(&handshake_handle,
+                &handshake_message,
+                *local_identity_handle_,
+                *remote_identity_handle,
+                exception);
+
+    if(ret == VALIDATION_FAILED)
+    {
+        restore_remote_identity_handle(remote_participant_key, remote_identity_handle);
+        return false;
+    }
+
+    assert(handshake_handle);
+    assert(handshake_message);
+
+    // Send hanshake message
+    // 
+    delete handshake_message;
+
+    AuthenticationStatus auth_status = AUTHENTICATION_FAILED;
+
+    switch(ret)
+    {
+        case VALIDATION_OK:
+            auth_status = AUTHENTICATION_OK;
+            break;
+        case VALIDATION_PENDING_HANDSHAKE_MESSAGE:
+            auth_status = AUTHENTICATION_WAITING_REPLY;
+            break;
+        case VALIDATION_OK_WITH_FINAL_MESSAGE:
+            auth_status = AUTHENTICATION_OK;
+            break;
+        case VALIDATION_PENDING_RETRY:
+            // TODO(Ricardo) Send event.
+        default:
+            restore_remote_identity_handle(remote_participant_key, remote_identity_handle);
+            return false;
+    };
+
+    // Store status
+    std::unique_lock<std::mutex> lock(mutex_);
+
+    auto dp_it = discovered_participants_.find(remote_participant_key);
+
+    if(dp_it != discovered_participants_.end())
+    {
+        assert(dp_it->second.get_auth_status() == AUTHENTICATION_REQUEST_NOT_SEND);
+        dp_it->second.set_auth_status(auth_status);
+        assert(dp_it->second.is_identity_handle_null());
+        dp_it->second.set_identity_handle(remote_identity_handle);
+        assert(dp_it->second.is_handshake_handle_null());
+        dp_it->second.set_handshake_handle(handshake_handle);
+    }
+    else
+    {
+        authentication_plugin_->return_handshake_handle(handshake_handle, exception);
+        authentication_plugin_->return_identity_handle(remote_identity_handle, exception);
+        return false;
+    }
+
+    return true;
+}
+
+bool SecurityManager::create_entities()
+{
+    if(create_participant_stateless_message_entities())
+    {
+        return true;
+    }
+
+    return false; 
+}
+
+bool SecurityManager::create_participant_stateless_message_entities()
+{
+    if(create_participant_stateless_message_writer())
+    {
+        if(create_participant_stateless_message_reader())
+        {
+            return true;
+        }
+
+        delete_participant_stateless_message_writer();
+    }
+
+    return false;
+}
+
+void SecurityManager::delete_participant_stateless_message_entities()
+{
+    delete_participant_stateless_message_reader();
+    delete_participant_stateless_message_writer();
+}
+
+bool SecurityManager::create_participant_stateless_message_writer()
+{
+    HistoryAttributes hatt;
+    hatt.payloadMaxSize = 5000;
+    hatt.initialReservedCaches = 20;
+    hatt.maximumReservedCaches = 100;
+    participant_stateless_message_writer_history_ = new WriterHistory(hatt);
+    WriterAttributes watt;
+    watt.endpoint.endpointKind = WRITER;
+    watt.endpoint.reliabilityKind = BEST_EFFORT;
+    watt.endpoint.topicKind = NO_KEY;
+
+    if(participant_->getRTPSParticipantAttributes().throughputController.bytesPerPeriod != UINT32_MAX &&
+            participant_->getRTPSParticipantAttributes().throughputController.periodMillisecs != 0)
+        watt.mode = ASYNCHRONOUS_WRITER;
+
+    RTPSWriter* wout = nullptr;
+    if(participant_->createWriter(&wout, watt, participant_stateless_message_writer_history_, nullptr, participant_stateless_message_writer_entity_id, true))
+    {
+        participant_stateless_message_writer_ = dynamic_cast<StatelessWriter*>(wout);
+
+        return true;
+    }
+
+    logError(SECURITY,"Participant Stateless Message Writer creation failed");
+    delete(participant_stateless_message_writer_history_);
+    participant_stateless_message_writer_history_ = nullptr;
+
+    return false;
+}
+
+void SecurityManager::delete_participant_stateless_message_writer()
+{
+    if(participant_stateless_message_writer_ != nullptr)
+        delete participant_stateless_message_writer_;
+
+    if(participant_stateless_message_writer_history_ != nullptr)
+        delete participant_stateless_message_writer_history_;
+}
+
+bool SecurityManager::create_participant_stateless_message_reader()
+{
+    HistoryAttributes hatt;
+    hatt.payloadMaxSize = 5000;
+    hatt.initialReservedCaches = 250;
+    hatt.maximumReservedCaches = 5000;
+    participant_stateless_message_reader_history_ = new ReaderHistory(hatt);
+    ReaderAttributes ratt;
+    ratt.endpoint.topicKind = NO_KEY;
+    ratt.endpoint.reliabilityKind = BEST_EFFORT;
+    //mp_listener = new PDPSimpleListener(this);
+
+    RTPSReader* rout = nullptr;
+    if(participant_->createReader(&rout, ratt, participant_stateless_message_reader_history_, nullptr, participant_stateless_message_reader_entity_id, true, false))
+    {
+        participant_stateless_message_reader_ = dynamic_cast<StatelessReader*>(rout);
+
+        return true;
+    }
+
+    logError(SECURITY,"Participant Stateless Message Reader creation failed");
+    delete(participant_stateless_message_reader_history_);
+    participant_stateless_message_reader_history_ = nullptr;
+    //delete(mp_listener);
+    //mp_listener = nullptr;
+    return false;
+}
+
+void SecurityManager::delete_participant_stateless_message_reader()
+{
+    if(participant_stateless_message_reader_ != nullptr)
+        delete participant_stateless_message_reader_;
+
+    if(participant_stateless_message_reader_history_ != nullptr)
+        delete participant_stateless_message_reader_history_;
 }
diff --git a/src/cpp/rtps/security/SecurityManager.h b/src/cpp/rtps/security/SecurityManager.h
index 71ce9f20..9053abc9 100644
--- a/src/cpp/rtps/security/SecurityManager.h
+++ b/src/cpp/rtps/security/SecurityManager.h
@@ -16,21 +16,161 @@
  * @file SecurityManager.h
  */
 #ifndef _RTPS_SECURITY_SECURITYMANAGER_H_
 #define _RTPS_SECURITY_SECURITYMANAGER_H_
 
+#include "SecurityPluginFactory.h"
+
+#include <fastrtps/rtps/security/authentication/Handshake.h>
+
+#include <map>
+#include <mutex>
+
 namespace eprosima {
 namespace fastrtps {
 namespace rtps {
+
+class RTPSParticipantImpl;
+class StatelessWriter;
+class StatelessReader;
+class WriterHistory;
+class ReaderHistory;
+
 namespace security {
 
+class Authentication;
 
 class SecurityManager
 {
     public:
 
-        SecurityManager();
+        SecurityManager(RTPSParticipantImpl* participant);
+
+        ~SecurityManager();
+
+        bool init();
+
+        bool discovered_participant(IdentityToken&& remote_identity_token,
+                const GUID_t& remote_participant_key);
+
+    private:
+
+        enum AuthenticationStatus : uint32_t
+        {
+            AUTHENTICATION_OK = 0,
+            AUTHENTICATION_FAILED,
+            AUTHENTICATION_INIT,
+            AUTHENTICATION_REQUEST_NOT_SEND,
+            AUTHENTICATION_WAITING_REQUEST,
+            AUTHENTICATION_WAITING_REPLY,
+            AUTHENTICATION_WAITING_FINAL
+        };
+
+        class DiscoveredParticipantInfo
+        {
+            public:
+
+                DiscoveredParticipantInfo(AuthenticationStatus auth_status) :
+                    identity_handle_(nullptr), handshake_handle_(nullptr),
+                    auth_status_(auth_status){}
+
+                bool is_identity_handle_null()
+                {
+                    return identity_handle_ == nullptr;
+                }
+
+                bool set_identity_handle(IdentityHandle* identity_handle)
+                {
+                    if(identity_handle_ == nullptr)
+                    {
+                        identity_handle_ = identity_handle;
+                        return true;
+                    }
+
+                    return false;
+                }
+
+                IdentityHandle* get_identity_handle()
+                {
+                    IdentityHandle* handle = identity_handle_;
+                    identity_handle_ = nullptr;
+                    return handle;
+                }
+
+                bool is_handshake_handle_null()
+                {
+                    return handshake_handle_ == nullptr;
+                }
+
+                bool set_handshake_handle(HandshakeHandle* handshake_handle)
+                {
+                    if(handshake_handle_ == nullptr)
+                    {
+                        handshake_handle_ = handshake_handle;
+                        return true;
+                    }
+
+                    return false;
+                }
+
+                HandshakeHandle* get_handshake_handle()
+                {
+                    HandshakeHandle* handle = handshake_handle_;
+                    handshake_handle_ = nullptr;
+                    return handle;
+                }
+
+                AuthenticationStatus get_auth_status()
+                {
+                    return auth_status_;
+                }
+
+                void set_auth_status(AuthenticationStatus auth_status)
+                {
+                    auth_status_ = auth_status;
+                }
+
+            private:
+
+                DiscoveredParticipantInfo(const DiscoveredParticipantInfo& info) = delete;
+
+                IdentityHandle* identity_handle_;
+
+                HandshakeHandle* handshake_handle_;
+
+                AuthenticationStatus auth_status_;
+        };
+
+        void remove_discovered_participant_info(const GUID_t remote_participant_key);
+        void restore_remote_identity_handle(const GUID_t& remote_participant_key,
+                IdentityHandle* remote_identity_handle);
+
+        bool create_entities();
+        void delete_entities();
+        bool create_participant_stateless_message_entities();
+        void delete_participant_stateless_message_entities();
+        bool create_participant_stateless_message_writer();
+        void delete_participant_stateless_message_writer();
+        bool create_participant_stateless_message_reader();
+        void delete_participant_stateless_message_reader();
+
+        bool on_request_not_send(const GUID_t& remote_participant_key, IdentityHandle* remote_identity_handle);
+
+        RTPSParticipantImpl* participant_;
+        StatelessWriter* participant_stateless_message_writer_;
+        WriterHistory* participant_stateless_message_writer_history_;
+        StatelessReader* participant_stateless_message_reader_;
+        ReaderHistory* participant_stateless_message_reader_history_;
+        SecurityPluginFactory factory_;
+
+        Authentication* authentication_plugin_;
+
+        IdentityHandle* local_identity_handle_;
+
+        std::map<GUID_t, DiscoveredParticipantInfo> discovered_participants_;
+
+        std::mutex mutex_;
 };
 
 } //namespace security
 } //namespace rtps
 } //namespace fastrtps
diff --git a/src/cpp/security/authentication/PKIDH.cpp b/src/cpp/security/authentication/PKIDH.cpp
index 7fd1fe12..406cea2f 100644
--- a/src/cpp/security/authentication/PKIDH.cpp
+++ b/src/cpp/security/authentication/PKIDH.cpp
@@ -996,11 +996,11 @@ ValidationResult_t PKIDH::validate_local_identity(IdentityHandle** local_identit
 }
 
 ValidationResult_t PKIDH::validate_remote_identity(IdentityHandle** remote_identity_handle,
         const IdentityHandle& local_identity_handle,
         IdentityToken&& remote_identity_token,
-        const GUID_t remote_participant_key,
+        const GUID_t& remote_participant_key,
         SecurityException& exception)
 {
     assert(remote_identity_handle);
     assert(local_identity_handle.nil() == false);
 
diff --git a/src/cpp/security/authentication/PKIDH.h b/src/cpp/security/authentication/PKIDH.h
index 4810e128..0dc89ce9 100644
--- a/src/cpp/security/authentication/PKIDH.h
+++ b/src/cpp/security/authentication/PKIDH.h
@@ -40,11 +40,11 @@ class PKIDH : public Authentication
                 SecurityException& exception);
 
         ValidationResult_t validate_remote_identity(IdentityHandle** remote_identity_handle,
                 const IdentityHandle& local_identity_handle,
                 IdentityToken&& remote_identity_token,
-                const GUID_t remote_participant_key,
+                const GUID_t& remote_participant_key,
                 SecurityException& exception);
 
         ValidationResult_t begin_handshake_request(HandshakeHandle** handshake_handle,
                 HandshakeMessageToken** handshake_message,
                 const IdentityHandle& initiator_identity_handle,
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a92453c9..bd555eaa 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -27,5 +27,6 @@ add_subdirectory(unittest/rtps/ros2features)
 add_subdirectory(unittest/rtps/network)
 add_subdirectory(unittest/rtps/flowcontrol)
 add_subdirectory(unittest/transport)
 add_subdirectory(unittest/logging)
 add_subdirectory(unittest/security/authentication)
+add_subdirectory(unittest/rtps/security)
diff --git a/test/mock/rtps/RTPSParticipantImpl/rtps/participant/RTPSParticipantImpl.h b/test/mock/rtps/RTPSParticipantImpl/rtps/participant/RTPSParticipantImpl.h
new file mode 100644
index 00000000..3442ba2f
--- /dev/null
+++ b/test/mock/rtps/RTPSParticipantImpl/rtps/participant/RTPSParticipantImpl.h
@@ -0,0 +1,59 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @file RTPSParticipantImpl.h
+ */
+
+#ifndef RTPS_PARTICIPANT_RTPSPARTICIPANTIMPL_H_
+#define RTPS_PARTICIPANT_RTPSPARTICIPANTIMPL_H_
+
+#include <fastrtps/rtps/attributes/WriterAttributes.h>
+#include <fastrtps/rtps/attributes/ReaderAttributes.h>
+
+#include <gmock/gmock.h>
+
+namespace eprosima {
+namespace fastrtps {
+namespace rtps {
+
+class RTPSWriter;
+class RTPSReader;
+class WriterHistory;
+class ReaderHistory;
+class WriterListener;
+class ReaderListener;
+class EntityId_t;
+
+class RTPSParticipantImpl
+{
+    public:
+
+        MOCK_CONST_METHOD0(getRTPSParticipantAttributes, const RTPSParticipantAttributes&());
+
+        MOCK_CONST_METHOD0(getGuid, const GUID_t&());
+
+        MOCK_METHOD6(createWriter, bool (RTPSWriter** Writer, WriterAttributes& param, WriterHistory* hist,WriterListener* listen,
+                const EntityId_t& entityId, bool isBuiltin));
+
+        MOCK_METHOD7(createReader, bool (RTPSReader** Reader, ReaderAttributes& param, ReaderHistory* hist,ReaderListener* listen,
+                const EntityId_t& entityId, bool isBuiltin, bool enable));
+};
+
+} // namespace rtps
+} // namespace fastrtps
+} // namespace eprosima
+
+#endif // RTPS_PARTICIPANT_RTPSPARTICIPANTIMPL_H_
+
diff --git a/test/mock/rtps/RTPSReader/fastrtps/rtps/reader/RTPSReader.h b/test/mock/rtps/RTPSReader/fastrtps/rtps/reader/RTPSReader.h
new file mode 100644
index 00000000..f9c0bb30
--- /dev/null
+++ b/test/mock/rtps/RTPSReader/fastrtps/rtps/reader/RTPSReader.h
@@ -0,0 +1,39 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @file RTPSReader.h
+ */
+
+#ifndef _RTPS_READER_RTPSREADER_H_
+#define _RTPS_READER_RTPSREADER_H_
+
+namespace eprosima {
+namespace fastrtps {
+namespace rtps {
+
+class RTPSReader
+{
+    public:
+
+        virtual bool matched_writer_add(RemoteWriterAttributes& wdata) = 0;
+
+        virtual bool matched_writer_remove(RemoteWriterAttributes& wdata) = 0;
+};
+
+} // namespace rtps
+} // namespace fastrtps
+} // namespace eprosima
+
+#endif // _RTPS_READER_RTPSREADER_H_
diff --git a/test/mock/rtps/RTPSWriter/fastrtps/rtps/writer/RTPSWriter.h b/test/mock/rtps/RTPSWriter/fastrtps/rtps/writer/RTPSWriter.h
new file mode 100644
index 00000000..a0fbf553
--- /dev/null
+++ b/test/mock/rtps/RTPSWriter/fastrtps/rtps/writer/RTPSWriter.h
@@ -0,0 +1,39 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @file RTPSWriter.h
+ */
+
+#ifndef _RTPS_WRITER_RTPSWRITER_H_
+#define _RTPS_WRITER_RTPSWRITER_H_
+
+namespace eprosima {
+namespace fastrtps {
+namespace rtps {
+
+class RTPSWriter
+{
+    public:
+
+        virtual bool matched_reader_add(RemoteReaderAttributes& ratt) = 0;
+
+        virtual bool matched_reader_remove(RemoteReaderAttributes& ratt) = 0;
+};
+
+} // namespace rtps
+} // namespace fastrtps
+} // namespace eprosima
+
+#endif // _RTPS_WRITER_RTPSWRITER_H_
diff --git a/test/mock/rtps/ReaderHistory/fastrtps/rtps/history/ReaderHistory.h b/test/mock/rtps/ReaderHistory/fastrtps/rtps/history/ReaderHistory.h
new file mode 100644
index 00000000..5f9e85a2
--- /dev/null
+++ b/test/mock/rtps/ReaderHistory/fastrtps/rtps/history/ReaderHistory.h
@@ -0,0 +1,39 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @file ReaderHistory.h
+ */
+
+#ifndef _RTPS_HISTORY_READERHISTORY_H_
+#define _RTPS_HISTORY_READERHISTORY_H_
+
+#include <fastrtps/rtps/attributes/HistoryAttributes.h>
+
+namespace eprosima {
+namespace fastrtps {
+namespace rtps {
+
+class ReaderHistory
+{
+    public:
+
+        ReaderHistory(const HistoryAttributes& /*att*/){}
+};
+
+} // namespace rtps
+} // namespace fastrtps
+} // namespace eprosima
+
+#endif // _RTPS_HISTORY_READERHISTORY_H_
diff --git a/test/mock/rtps/SecurityPluginFactory/MockAuthenticationPlugin.h b/test/mock/rtps/SecurityPluginFactory/MockAuthenticationPlugin.h
new file mode 100644
index 00000000..6b10ff00
--- /dev/null
+++ b/test/mock/rtps/SecurityPluginFactory/MockAuthenticationPlugin.h
@@ -0,0 +1,125 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*!
+ * @file MockAuthenticationPlugin.h
+ */
+
+#ifndef _SECURITY_MOCKAUTHENTICATIONPLUGIN_H_
+#define _SECURITY_MOCKAUTHENTICATIONPLUGIN_H_
+
+// TODO(Ricardo) Change when GMock supports r-values.
+
+#include <fastrtps/rtps/security/authentication/Authentication.h>
+#include <gmock/gmock.h>
+
+namespace eprosima {
+namespace fastrtps {
+namespace rtps {
+namespace security {
+
+class MockAuthenticationPlugin : public Authentication
+{
+    public:
+
+        MOCK_METHOD6(validate_local_identity, ValidationResult_t(IdentityHandle** local_identity_handle,
+                GUID_t& adjusted_participant_key,
+                const uint32_t domain_id,
+                const RTPSParticipantAttributes& participant_attr,
+                const GUID_t& candidate_participant_key,
+                SecurityException& exception));
+
+        MOCK_METHOD5(validate_remote_identity_rvr, ValidationResult_t(IdentityHandle** remote_identity_handle,
+                const IdentityHandle& local_identity_handle,
+                IdentityToken remote_identity_token,
+                const GUID_t& remote_participant_key,
+                SecurityException& exception));
+
+        MOCK_METHOD5(begin_handshake_request, ValidationResult_t(HandshakeHandle** handshake_handle,
+                HandshakeMessageToken** handshake_message,
+                const IdentityHandle& initiator_identity_handle,
+                IdentityHandle& replier_identity_handle,
+                SecurityException& exception));
+
+        MOCK_METHOD6(begin_handshake_reply_rvr, ValidationResult_t(HandshakeHandle** handshake_handle,
+                HandshakeMessageToken** handshake_message_out,
+                HandshakeMessageToken handshake_message_in,
+                IdentityHandle& initiator_identity_handle,
+                const IdentityHandle& replier_identity_handle,
+                SecurityException& exception));
+
+        MOCK_METHOD4(process_handshake_rvr, ValidationResult_t(HandshakeMessageToken** handshake_message_out,
+                HandshakeMessageToken handshake_message_in,
+                HandshakeHandle& handshake_handle,
+                SecurityException& exception));
+
+        MOCK_METHOD2(get_shared_secret, SharedSecretHandle*(const HandshakeHandle& handshake_handle,
+                SecurityException& exception));
+
+        MOCK_METHOD2(set_listener, bool(AuthenticationListener* listener,
+                SecurityException& exception));
+
+        MOCK_METHOD3(get_identity_token, bool(IdentityToken** identity_token,
+                const IdentityHandle& handle,
+                SecurityException& exception));
+
+        MOCK_METHOD2(return_identity_token, bool(IdentityToken* token,
+                SecurityException& exception));
+
+        MOCK_METHOD2(return_handshake_handle, bool(HandshakeHandle* handshake_handle,
+                SecurityException& exception));
+
+        MOCK_METHOD2(return_identity_handle, bool(IdentityHandle* identity_handle,
+                SecurityException& exception));
+
+        MOCK_METHOD2(return_sharedsecret_handle, bool(SharedSecretHandle* sharedsecret_handle,
+                SecurityException& exception));
+
+        ValidationResult_t validate_remote_identity(IdentityHandle** remote_identity_handle,
+                const IdentityHandle& local_identity_handle,
+                IdentityToken&& remote_identity_token,
+                const GUID_t& remote_participant_key,
+                SecurityException& exception)
+        {
+            return validate_remote_identity_rvr(remote_identity_handle, local_identity_handle,
+                    remote_identity_token, remote_participant_key, exception);
+        }
+
+        ValidationResult_t begin_handshake_reply(HandshakeHandle** handshake_handle,
+                HandshakeMessageToken** handshake_message_out,
+                HandshakeMessageToken&& handshake_message_in,
+                IdentityHandle& initiator_identity_handle,
+                const IdentityHandle& replier_identity_handle,
+                SecurityException& exception)
+        {
+            return begin_handshake_reply_rvr(handshake_handle, handshake_message_out, handshake_message_in,
+                    initiator_identity_handle, replier_identity_handle, exception);
+        }
+
+        ValidationResult_t process_handshake(HandshakeMessageToken** handshake_message_out,
+                HandshakeMessageToken&& handshake_message_in,
+                HandshakeHandle& handshake_handle,
+                SecurityException& exception)
+        {
+            return process_handshake_rvr(handshake_message_out, handshake_message_in,
+                    handshake_handle, exception);
+        }
+};
+
+} // namespace security
+} // namespace rtps
+} // namespace fastrtps
+} // namespace eprosima
+
+#endif // _SECURITY_MOCKAUTHENTICATIONPLUGIN_H_
diff --git a/test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.cpp b/test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.cpp
new file mode 100644
index 00000000..60f7b707
--- /dev/null
+++ b/test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.cpp
@@ -0,0 +1,39 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*!
+ * @file SecurityPluginFactory.cpp
+ */
+
+#include "SecurityPluginFactory.h"
+
+using namespace eprosima::fastrtps::rtps;
+using namespace ::security;
+
+Authentication* SecurityPluginFactory::auth_plugin_ = nullptr;
+
+Authentication* SecurityPluginFactory::create_authentication_plugin(const PropertyPolicy& /*property_policy*/)
+{
+    return auth_plugin_;
+}
+
+void SecurityPluginFactory::set_auth_plugin(Authentication* plugin)
+{
+    auth_plugin_ = plugin;
+}
+
+void SecurityPluginFactory::release_auth_plugin()
+{
+    auth_plugin_ = nullptr;
+}
diff --git a/test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.h b/test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.h
new file mode 100644
index 00000000..d92865bd
--- /dev/null
+++ b/test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.h
@@ -0,0 +1,55 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*!
+ * @file SecurityPluginFactory.h
+ */
+#ifndef _RTPS_SECURITY_SECURITYPLUGINFACTORY_H_
+#define _RTPS_SECURITY_SECURITYPLUGINFACTORY_H_
+
+#include <fastrtps/rtps/security/authentication/Authentication.h>
+#include <fastrtps/rtps/attributes/PropertyPolicy.h>
+
+namespace eprosima {
+namespace fastrtps {
+namespace rtps {
+namespace security {
+
+class SecurityPluginFactory
+{
+    public:
+
+        /*!
+         * @brief Create an Authentication plugin  described in the PropertyPolicy.
+         * @param property_policy PropertyPolicy containing the definition of the Authentication
+         * plugin that has to be created.
+         * @param Pointer to the new Authentication plugin. In case of error nullptr will be returned.
+         */
+        Authentication* create_authentication_plugin(const PropertyPolicy& property_policy);
+
+        static void set_auth_plugin(Authentication* plugin);
+
+        static void release_auth_plugin();
+
+    private:
+
+        static Authentication* auth_plugin_;
+};
+
+} //namespace security
+} //namespace rtps
+} //namespace fastrtps
+} //namespace eprosima
+
+#endif // _RTPS_SECURITY_SECURITYPLUGINFACTORY_H_
diff --git a/test/mock/rtps/StatelessReader/fastrtps/rtps/reader/StatelessReader.h b/test/mock/rtps/StatelessReader/fastrtps/rtps/reader/StatelessReader.h
new file mode 100644
index 00000000..2f13156e
--- /dev/null
+++ b/test/mock/rtps/StatelessReader/fastrtps/rtps/reader/StatelessReader.h
@@ -0,0 +1,41 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @file StatelessReader.h
+ */
+
+#ifndef _RTPS_READER_STATELESSREADER_H_
+#define _RTPS_READER_STATELESSREADER_H_
+
+#include <fastrtps/rtps/reader/RTPSReader.h>
+
+namespace eprosima {
+namespace fastrtps {
+namespace rtps {
+
+class StatelessReader : public RTPSReader
+{
+    public:
+
+        MOCK_METHOD1(matched_writer_add, bool(RemoteWriterAttributes&));
+
+        MOCK_METHOD1(matched_writer_remove, bool(RemoteWriterAttributes&));
+};
+
+} // namespace rtps
+} // namespace fastrtps
+} // namespace eprosima
+
+#endif // _RTPS_READER_STATELESSREADER_H_
diff --git a/test/mock/rtps/StatelessWriter/fastrtps/rtps/writer/StatelessWriter.h b/test/mock/rtps/StatelessWriter/fastrtps/rtps/writer/StatelessWriter.h
new file mode 100644
index 00000000..9ca48188
--- /dev/null
+++ b/test/mock/rtps/StatelessWriter/fastrtps/rtps/writer/StatelessWriter.h
@@ -0,0 +1,41 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @file StatelessWriter.h
+ */
+
+#ifndef _RTPS_WRITER_STATELESSWRITER_H_
+#define _RTPS_WRITER_STATELESSWRITER_H_
+
+#include <fastrtps/rtps/writer/RTPSWriter.h>
+
+namespace eprosima {
+namespace fastrtps {
+namespace rtps {
+
+class StatelessWriter : public RTPSWriter
+{
+    public:
+
+        MOCK_METHOD1(matched_reader_add, bool(RemoteReaderAttributes&));
+
+        MOCK_METHOD1(matched_reader_remove, bool(RemoteReaderAttributes&));
+};
+
+} // namespace rtps
+} // namespace fastrtps
+} // namespace eprosima
+
+#endif // _RTPS_WRITER_STATELESSWRITER_H_
diff --git a/test/mock/rtps/WriterHistory/fastrtps/rtps/history/WriterHistory.h b/test/mock/rtps/WriterHistory/fastrtps/rtps/history/WriterHistory.h
new file mode 100644
index 00000000..9a7d51f4
--- /dev/null
+++ b/test/mock/rtps/WriterHistory/fastrtps/rtps/history/WriterHistory.h
@@ -0,0 +1,40 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @file WriterHistory.h
+ */
+
+#ifndef _RTPS_HISTORY_WRITERHISTORY_H_
+#define _RTPS_HISTORY_WRITERHISTORY_H_
+
+#include <fastrtps/rtps/attributes/HistoryAttributes.h>
+
+namespace eprosima {
+namespace fastrtps {
+namespace rtps {
+
+class WriterHistory
+{
+    public:
+
+
+        WriterHistory(const HistoryAttributes& /*att*/){}
+};
+
+} // namespace rtps
+} // namespace fastrtps
+} // namespace eprosima
+
+#endif // _RTPS_HISTORY_WRITERHISTORY_H_
diff --git a/test/unittest/rtps/security/CMakeLists.txt b/test/unittest/rtps/security/CMakeLists.txt
new file mode 100644
index 00000000..d15192a3
--- /dev/null
+++ b/test/unittest/rtps/security/CMakeLists.txt
@@ -0,0 +1,53 @@
+# Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER))
+    include(${PROJECT_SOURCE_DIR}/cmake/dev/gtest.cmake)
+    check_gtest()
+    check_gmock()
+
+    if(GTEST_FOUND AND GMOCK_FOUND)
+        if(WIN32)
+            add_definitions(-D_WIN32_WINNT=0x0601)
+        endif()
+
+        set(SOURCES_SECURITY_TEST_SOURCE
+            ${PROJECT_SOURCE_DIR}/src/cpp/log/Log.cpp
+            ${PROJECT_SOURCE_DIR}/src/cpp/log/StdoutConsumer.cpp
+            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/attributes/PropertyPolicy.cpp
+            ${PROJECT_SOURCE_DIR}/test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.cpp
+            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/SecurityManager.cpp
+            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/exceptions/Exception.cpp
+            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/exceptions/SecurityException.cpp
+            )
+
+        add_executable(SecurityAuthentication ${SOURCES_SECURITY_TEST_SOURCE}
+            ${CMAKE_CURRENT_SOURCE_DIR}/SecurityAuthenticationTests.cpp)
+        add_gtest(SecurityAuthentication 
+            ${CMAKE_CURRENT_SOURCE_DIR}/SecurityAuthenticationTests.cpp)
+        target_include_directories(SecurityAuthentication PRIVATE
+            ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS}
+            ${PROJECT_SOURCE_DIR}/test/mock/rtps/SecurityPluginFactory
+            ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSParticipantImpl
+            ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSWriter
+            ${PROJECT_SOURCE_DIR}/test/mock/rtps/StatelessWriter
+            ${PROJECT_SOURCE_DIR}/test/mock/rtps/WriterHistory
+            ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSReader
+            ${PROJECT_SOURCE_DIR}/test/mock/rtps/StatelessReader
+            ${PROJECT_SOURCE_DIR}/test/mock/rtps/ReaderHistory
+            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security
+            ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include/${PROJECT_NAME})
+        target_link_libraries(SecurityAuthentication ${Boost_LIBRARIES} ${GMOCK_LIBRARIES})
+    endif()
+endif()
diff --git a/test/unittest/rtps/security/SecurityAuthenticationTests.cpp b/test/unittest/rtps/security/SecurityAuthenticationTests.cpp
new file mode 100644
index 00000000..0deed4f8
--- /dev/null
+++ b/test/unittest/rtps/security/SecurityAuthenticationTests.cpp
@@ -0,0 +1,341 @@
+// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <fastrtps/rtps/security/common/Handle.h>
+#include <MockAuthenticationPlugin.h>
+#include <rtps/participant/RTPSParticipantImpl.h>
+#include <SecurityPluginFactory.h>
+#include <SecurityManager.h>
+
+#include <gtest/gtest.h>
+
+using namespace eprosima::fastrtps::rtps;
+using namespace ::security;
+using namespace ::testing;
+
+using ::testing::DefaultValue;
+
+class MockIdentity
+{
+    public:
+
+        static const char* const class_id_;
+};
+
+const char* const MockIdentity::class_id_ = "MockIdentityHandle";
+
+typedef HandleImpl<MockIdentity> MockIdentityHandle;
+
+class MockHandshake
+{
+    public:
+
+        static const char* const class_id_;
+};
+
+const char* const MockHandshake::class_id_ = "MockHandshakeHandle";
+
+typedef HandleImpl<MockHandshake> MockHandshakeHandle;
+
+// Default Values
+RTPSParticipantAttributes pattr;
+GUID_t guid;
+
+class SecurityAuthenticationTest : public ::testing::Test
+{
+    protected:
+
+        virtual void SetUp()
+        {
+            SecurityPluginFactory::set_auth_plugin(auth_plugin_);
+        }
+
+        virtual void TearDown()
+        {
+            SecurityPluginFactory::release_auth_plugin();
+        }
+
+        void initialization_ok()
+        {
+            DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
+            DefaultValue<const GUID_t&>::Set(guid);
+            MockIdentityHandle identity_handle;
+            MockIdentityHandle* p_identity_handle = &identity_handle;
+
+            EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(1).
+                WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));
+            EXPECT_CALL(participant_, createWriter(_,_,_,_,_,_)).Times(1).
+                WillOnce(Return(true));
+            EXPECT_CALL(participant_, createReader(_,_,_,_,_,_,_)).Times(1).
+                WillOnce(Return(true));
+
+            ASSERT_TRUE(manager_.init());
+        }
+
+
+    public:
+
+        SecurityAuthenticationTest() : auth_plugin_(new MockAuthenticationPlugin()), manager_(&participant_) {}
+        MockAuthenticationPlugin* auth_plugin_;
+        NiceMock<RTPSParticipantImpl> participant_;
+        SecurityManager manager_;
+};
+
+TEST_F(SecurityAuthenticationTest, initialization_auth_nullptr)
+{
+    SecurityPluginFactory::release_auth_plugin();
+    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
+    DefaultValue<const GUID_t&>::Set(guid);
+
+    ASSERT_FALSE(manager_.init());
+}
+
+TEST_F(SecurityAuthenticationTest, initialization_auth_failed)
+{
+    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
+    DefaultValue<const GUID_t&>::Set(guid);
+
+    EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(1).
+        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));
+
+    ASSERT_FALSE(manager_.init());
+}
+
+TEST_F(SecurityAuthenticationTest, initialization_fail_participant_stateless_message_writer)
+{
+    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
+    DefaultValue<const GUID_t&>::Set(guid);
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+
+    EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));
+    EXPECT_CALL(participant_, createWriter(_,_,_,_,_,_)).Times(1).
+        WillOnce(Return(false));
+
+    ASSERT_FALSE(manager_.init());
+}
+
+TEST_F(SecurityAuthenticationTest, initialization_fail_participant_stateless_message_reader)
+{
+    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
+    DefaultValue<const GUID_t&>::Set(guid);
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+
+    EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));
+    EXPECT_CALL(participant_, createWriter(_,_,_,_,_,_)).Times(1).
+        WillOnce(Return(true));
+    EXPECT_CALL(participant_, createReader(_,_,_,_,_,_,_)).Times(1).
+        WillOnce(Return(false));
+
+    ASSERT_FALSE(manager_.init());
+}
+
+TEST_F(SecurityAuthenticationTest, initialization_auth_retry)
+{
+    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
+    DefaultValue<const GUID_t&>::Set(guid);
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+
+    EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(2).
+        WillOnce(Return(ValidationResult_t::VALIDATION_PENDING_RETRY)).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));
+    EXPECT_CALL(participant_, createWriter(_,_,_,_,_,_)).Times(1).
+        WillOnce(Return(true));
+    EXPECT_CALL(participant_, createReader(_,_,_,_,_,_,_)).Times(1).
+        WillOnce(Return(true));
+
+    ASSERT_TRUE(manager_.init());
+}
+
+
+TEST_F(SecurityAuthenticationTest, initialization_ok)
+{
+    initialization_ok();
+}
+
+TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_fail)
+{
+    initialization_ok();
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));
+
+    GUID_t remote_participant_key;
+    ASSERT_FALSE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+}
+
+TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_ok)
+{
+    initialization_ok();
+
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));
+
+    GUID_t remote_participant_key;
+    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+}
+
+TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_pending_handshake_message)
+{
+    initialization_ok();
+
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_MESSAGE)));
+
+    GUID_t remote_participant_key;
+    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+}
+
+TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_pending_handshake_request_fail)
+{
+    initialization_ok();
+
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
+    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
+        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));
+
+    GUID_t remote_participant_key;
+    ASSERT_FALSE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+}
+
+TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_pending_handshake_request_ok)
+{
+    initialization_ok();
+
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+    MockHandshakeHandle handshake_handle;
+    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
+    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
+    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
+                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_OK)));
+
+    GUID_t remote_participant_key;
+    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+}
+
+TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_pending_handshake_request_ok_with_final_message)
+{
+    initialization_ok();
+
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+    MockHandshakeHandle handshake_handle;
+    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
+    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
+    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
+                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_OK_WITH_FINAL_MESSAGE)));
+
+    GUID_t remote_participant_key;
+    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+}
+
+TEST_F(SecurityAuthenticationTest, discovered_participant_ok)
+{
+    initialization_ok();
+
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+    MockHandshakeHandle handshake_handle;
+    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
+    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
+    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
+                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_MESSAGE)));
+
+    GUID_t remote_participant_key;
+    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+}
+
+TEST_F(SecurityAuthenticationTest, discovered_participant_validate_remote_fail_and_then_ok)
+{
+    initialization_ok();
+
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+    MockHandshakeHandle handshake_handle;
+    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
+    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));
+
+    GUID_t remote_participant_key;
+    ASSERT_FALSE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
+    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
+                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_MESSAGE)));
+
+    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+}
+
+TEST_F(SecurityAuthenticationTest, discovered_participant_begin_handshake_request_fail_and_then_ok)
+{
+    initialization_ok();
+
+    MockIdentityHandle identity_handle;
+    MockIdentityHandle* p_identity_handle = &identity_handle;
+    MockHandshakeHandle handshake_handle;
+    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
+    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
+    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
+        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));
+
+    GUID_t remote_participant_key;
+    ASSERT_FALSE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+
+    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(0);
+    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
+        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
+                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_MESSAGE)));
+
+    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
+}
+
+int main(int argc, char **argv)
+{
+    testing::InitGoogleMock(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/test/unittest/security/authentication/BuiltinPKIDHTests.cpp b/test/unittest/security/authentication/BuiltinPKIDHTests.cpp
index 38ed04bd..551d36df 100644
--- a/test/unittest/security/authentication/BuiltinPKIDHTests.cpp
+++ b/test/unittest/security/authentication/BuiltinPKIDHTests.cpp
@@ -692,6 +692,5 @@ int main(int argc, char **argv)
         exit(-1);
     }
 
     return RUN_ALL_TESTS();
 }
-

Vulnerable code:                 const GUID_t remote_participant_key,
#include <unordered_map>
        RTPSParticipantListener* plisten):	m_att(PParam), m_guid(guidP,c_EntityId_RTPSParticipant),
const RTPSParticipantAttributes& RTPSParticipantImpl::getRTPSParticipantAttributes() const
{
    return this->m_att;
}

 * @file RTPSParticipant.h
        inline const GUID_t& getGuid() const {return m_guid;};
        const GUID_t m_guid;
        const RTPSParticipantAttributes& getRTPSParticipantAttributes() const;
using namespace eprosima::fastrtps::rtps::security;
SecurityManager::SecurityManager()
        SecurityManager();
        const GUID_t remote_participant_key,
                const GUID_t remote_participant_key,

Fixed code:                 const GUID_t& remote_participant_key,
            $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/cpp>
            $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/cpp>
        $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/cpp>
        RTPSParticipantListener* plisten):	m_att(PParam), m_guid(guidP ,c_EntityId_RTPSParticipant),
 * @file RTPSParticipantImpl.h
        inline const GUID_t& getGuid() const { return m_guid; }

        void setGuid(GUID_t& guid) { m_guid = guid; }
        GUID_t m_guid;
        const RTPSParticipantAttributes& getRTPSParticipantAttributes() const
        {
            return this->m_att;
        }
#include <fastrtps/log/Log.h>
#include <rtps/participant/RTPSParticipantImpl.h>
#include <fastrtps/rtps/writer/StatelessWriter.h>
#include <fastrtps/rtps/reader/StatelessReader.h>
#include <fastrtps/rtps/history/WriterHistory.h>
#include <fastrtps/rtps/history/ReaderHistory.h>
#include <fastrtps/rtps/attributes/HistoryAttributes.h>
#include <cassert>
#include <thread>

#define ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_WRITER  0x000201C2
#define ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_READER  0x000201C7

const EntityId_t participant_stateless_message_writer_entity_id = ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_WRITER;
const EntityId_t participant_stateless_message_reader_entity_id = ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_READER;

using namespace eprosima::fastrtps;
using namespace ::rtps;
using namespace ::security;

bool usleep_bool()
{
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    return true;
}

SecurityManager::SecurityManager(RTPSParticipantImpl *participant) : participant_(participant),
    participant_stateless_message_writer_(nullptr),
    participant_stateless_message_writer_history_(nullptr),
    participant_stateless_message_reader_(nullptr),
    participant_stateless_message_reader_history_(nullptr),
    authentication_plugin_(nullptr)
{
    assert(participant != nullptr);
}

SecurityManager::~SecurityManager()
{
    if(authentication_plugin_ != nullptr)
        delete authentication_plugin_;
}

bool SecurityManager::init()
{
    SecurityException exception;

    authentication_plugin_ = factory_.create_authentication_plugin(participant_->getRTPSParticipantAttributes().properties);

    if(authentication_plugin_ != nullptr)
    {
        // Validate local participant
        GUID_t adjusted_participant_key;
        ValidationResult_t ret = VALIDATION_FAILED;
        
        do
        {
            ret = authentication_plugin_->validate_local_identity(&local_identity_handle_,
                adjusted_participant_key,
                participant_->getRTPSParticipantAttributes().builtin.domainId,
                participant_->getRTPSParticipantAttributes(),
                participant_->getGuid(),
                exception);
        } while(ret == VALIDATION_PENDING_RETRY && usleep_bool());

        if(ret == VALIDATION_OK)
        {
            assert(local_identity_handle_ != nullptr);

            // Create RTPS entities
            if(create_entities())
            {
                return true;
            }
        }

        delete authentication_plugin_;
        authentication_plugin_ = nullptr;
    }
    else
    {
        logInfo(SECURITY, "Authentication plugin not configured. Security will be disable");
    }

    return false;
}

void SecurityManager::remove_discovered_participant_info(const GUID_t remote_participant_key)
{
    std::unique_lock<std::mutex> lock(mutex_);
    auto dp_it = discovered_participants_.find(remote_participant_key);

    if(dp_it != discovered_participants_.end())
    {
        IdentityHandle* identity_handle = dp_it->second.get_identity_handle();

        if(identity_handle != nullptr)
        {
            SecurityException exception;
            authentication_plugin_->return_identity_handle(identity_handle, exception);
        }

        discovered_participants_.erase(dp_it);
    }
}

void SecurityManager::restore_remote_identity_handle(const GUID_t& remote_participant_key,
        IdentityHandle* remote_identity_handle)
{
    SecurityException exception;

    std::unique_lock<std::mutex> lock(mutex_);
    auto dp_it = discovered_participants_.find(remote_participant_key);

    if(dp_it != discovered_participants_.end())
    {
        assert(dp_it->second.is_identity_handle_null());
        dp_it->second.set_identity_handle(remote_identity_handle);
    }
    else
        authentication_plugin_->return_identity_handle(remote_identity_handle, exception);
}

bool SecurityManager::discovered_participant(IdentityToken&& remote_identity_token,
        const GUID_t& remote_participant_key)
    IdentityHandle* remote_identity_handle = nullptr;
    SecurityException exception;
    AuthenticationStatus auth_status = AUTHENTICATION_INIT;

    // Find information
    mutex_.lock();
    auto dp_it = discovered_participants_.find(remote_participant_key);

    if(dp_it == discovered_participants_.end())
    {
        discovered_participants_.emplace(remote_participant_key, auth_status);

        mutex_.unlock();

        // Validate remote participant.
        ValidationResult_t validation_ret = authentication_plugin_->validate_remote_identity(&remote_identity_handle,
                *local_identity_handle_, std::move(remote_identity_token),
                remote_participant_key, exception);

        switch(validation_ret)
        {
            case VALIDATION_OK:
                assert(remote_identity_handle != nullptr);
                auth_status = AUTHENTICATION_OK;
                break;
            case VALIDATION_PENDING_HANDSHAKE_REQUEST:
                assert(remote_identity_handle != nullptr);
                auth_status = AUTHENTICATION_REQUEST_NOT_SEND;
                break;
            case VALIDATION_PENDING_HANDSHAKE_MESSAGE:
                assert(remote_identity_handle != nullptr);
                auth_status = AUTHENTICATION_WAITING_REQUEST;
                break;
            case VALIDATION_PENDING_RETRY:
                // TODO(Ricardo) Send event.
            default:
                remove_discovered_participant_info(remote_participant_key);
                return false;
        };

        // Store remote handle.
        mutex_.lock();
        dp_it = discovered_participants_.find(remote_participant_key);
        if(dp_it != discovered_participants_.end())
        {
            dp_it->second.set_auth_status(auth_status);
            bool ret = dp_it->second.set_identity_handle(remote_identity_handle);
            (void)ret; assert(ret);
            remote_identity_handle = nullptr;
        }
        else
        {
            mutex_.unlock();
            authentication_plugin_->return_identity_handle(remote_identity_handle, exception); // TODO(Ricardo) Check error.
            return false;
        }
    }
    else
    {
        auth_status = dp_it->second.get_auth_status();

        if(auth_status == AUTHENTICATION_INIT)
            return false;
    }

    if(auth_status == AUTHENTICATION_REQUEST_NOT_SEND)
    {
        remote_identity_handle = dp_it->second.get_identity_handle();
        assert(remote_identity_handle);
    }
    mutex_.unlock();

    bool returnedValue = true;

    // Maybe send request.
    if(remote_identity_handle != nullptr)
    {
        returnedValue = on_request_not_send(remote_participant_key, remote_identity_handle);
    }

    return returnedValue;
}

bool SecurityManager::on_request_not_send(const GUID_t& remote_participant_key,
        IdentityHandle* remote_identity_handle)
{
    assert(remote_identity_handle);

    HandshakeHandle* handshake_handle = nullptr;
    HandshakeMessageToken* handshake_message = nullptr;
    SecurityException exception;
    
    ValidationResult_t ret = authentication_plugin_->begin_handshake_request(&handshake_handle,
                &handshake_message,
                *local_identity_handle_,
                *remote_identity_handle,
                exception);

    if(ret == VALIDATION_FAILED)
    {
        restore_remote_identity_handle(remote_participant_key, remote_identity_handle);
        return false;
    }

    assert(handshake_handle);
    assert(handshake_message);

    // Send hanshake message
    // 
    delete handshake_message;

    AuthenticationStatus auth_status = AUTHENTICATION_FAILED;

    switch(ret)
    {
        case VALIDATION_OK:
            auth_status = AUTHENTICATION_OK;
            break;
        case VALIDATION_PENDING_HANDSHAKE_MESSAGE:
            auth_status = AUTHENTICATION_WAITING_REPLY;
            break;
        case VALIDATION_OK_WITH_FINAL_MESSAGE:
            auth_status = AUTHENTICATION_OK;
            break;
        case VALIDATION_PENDING_RETRY:
            // TODO(Ricardo) Send event.
        default:
            restore_remote_identity_handle(remote_participant_key, remote_identity_handle);
            return false;
    };

    // Store status
    std::unique_lock<std::mutex> lock(mutex_);

    auto dp_it = discovered_participants_.find(remote_participant_key);

    if(dp_it != discovered_participants_.end())
    {
        assert(dp_it->second.get_auth_status() == AUTHENTICATION_REQUEST_NOT_SEND);
        dp_it->second.set_auth_status(auth_status);
        assert(dp_it->second.is_identity_handle_null());
        dp_it->second.set_identity_handle(remote_identity_handle);
        assert(dp_it->second.is_handshake_handle_null());
        dp_it->second.set_handshake_handle(handshake_handle);
    }
    else
    {
        authentication_plugin_->return_handshake_handle(handshake_handle, exception);
        authentication_plugin_->return_identity_handle(remote_identity_handle, exception);
        return false;
    }

    return true;
}

bool SecurityManager::create_entities()
{
    if(create_participant_stateless_message_entities())
    {
        return true;
    }

    return false; 
}

bool SecurityManager::create_participant_stateless_message_entities()
{
    if(create_participant_stateless_message_writer())
    {
        if(create_participant_stateless_message_reader())
        {
            return true;
        }

        delete_participant_stateless_message_writer();
    }

    return false;
}

void SecurityManager::delete_participant_stateless_message_entities()
{
    delete_participant_stateless_message_reader();
    delete_participant_stateless_message_writer();
}

bool SecurityManager::create_participant_stateless_message_writer()
{
    HistoryAttributes hatt;
    hatt.payloadMaxSize = 5000;
    hatt.initialReservedCaches = 20;
    hatt.maximumReservedCaches = 100;
    participant_stateless_message_writer_history_ = new WriterHistory(hatt);
    WriterAttributes watt;
    watt.endpoint.endpointKind = WRITER;
    watt.endpoint.reliabilityKind = BEST_EFFORT;
    watt.endpoint.topicKind = NO_KEY;

    if(participant_->getRTPSParticipantAttributes().throughputController.bytesPerPeriod != UINT32_MAX &&
            participant_->getRTPSParticipantAttributes().throughputController.periodMillisecs != 0)
        watt.mode = ASYNCHRONOUS_WRITER;

    RTPSWriter* wout = nullptr;
    if(participant_->createWriter(&wout, watt, participant_stateless_message_writer_history_, nullptr, participant_stateless_message_writer_entity_id, true))
    {
        participant_stateless_message_writer_ = dynamic_cast<StatelessWriter*>(wout);

        return true;
    }

    logError(SECURITY,"Participant Stateless Message Writer creation failed");
    delete(participant_stateless_message_writer_history_);
    participant_stateless_message_writer_history_ = nullptr;

    return false;
}

void SecurityManager::delete_participant_stateless_message_writer()
{
    if(participant_stateless_message_writer_ != nullptr)
        delete participant_stateless_message_writer_;

    if(participant_stateless_message_writer_history_ != nullptr)
        delete participant_stateless_message_writer_history_;
}

bool SecurityManager::create_participant_stateless_message_reader()
{
    HistoryAttributes hatt;
    hatt.payloadMaxSize = 5000;
    hatt.initialReservedCaches = 250;
    hatt.maximumReservedCaches = 5000;
    participant_stateless_message_reader_history_ = new ReaderHistory(hatt);
    ReaderAttributes ratt;
    ratt.endpoint.topicKind = NO_KEY;
    ratt.endpoint.reliabilityKind = BEST_EFFORT;
    //mp_listener = new PDPSimpleListener(this);

    RTPSReader* rout = nullptr;
    if(participant_->createReader(&rout, ratt, participant_stateless_message_reader_history_, nullptr, participant_stateless_message_reader_entity_id, true, false))
    {
        participant_stateless_message_reader_ = dynamic_cast<StatelessReader*>(rout);

        return true;
    }

    logError(SECURITY,"Participant Stateless Message Reader creation failed");
    delete(participant_stateless_message_reader_history_);
    participant_stateless_message_reader_history_ = nullptr;
    //delete(mp_listener);
    //mp_listener = nullptr;
    return false;
}

void SecurityManager::delete_participant_stateless_message_reader()
{
    if(participant_stateless_message_reader_ != nullptr)
        delete participant_stateless_message_reader_;

    if(participant_stateless_message_reader_history_ != nullptr)
        delete participant_stateless_message_reader_history_;
#include "SecurityPluginFactory.h"

#include <fastrtps/rtps/security/authentication/Handshake.h>

#include <map>
#include <mutex>


class RTPSParticipantImpl;
class StatelessWriter;
class StatelessReader;
class WriterHistory;
class ReaderHistory;

class Authentication;
        SecurityManager(RTPSParticipantImpl* participant);

        ~SecurityManager();

        bool init();

        bool discovered_participant(IdentityToken&& remote_identity_token,
                const GUID_t& remote_participant_key);

    private:

        enum AuthenticationStatus : uint32_t
        {
            AUTHENTICATION_OK = 0,
            AUTHENTICATION_FAILED,
            AUTHENTICATION_INIT,
            AUTHENTICATION_REQUEST_NOT_SEND,
            AUTHENTICATION_WAITING_REQUEST,
            AUTHENTICATION_WAITING_REPLY,
            AUTHENTICATION_WAITING_FINAL
        };

        class DiscoveredParticipantInfo
        {
            public:

                DiscoveredParticipantInfo(AuthenticationStatus auth_status) :
                    identity_handle_(nullptr), handshake_handle_(nullptr),
                    auth_status_(auth_status){}

                bool is_identity_handle_null()
                {
                    return identity_handle_ == nullptr;
                }

                bool set_identity_handle(IdentityHandle* identity_handle)
                {
                    if(identity_handle_ == nullptr)
                    {
                        identity_handle_ = identity_handle;
                        return true;
                    }

                    return false;
                }

                IdentityHandle* get_identity_handle()
                {
                    IdentityHandle* handle = identity_handle_;
                    identity_handle_ = nullptr;
                    return handle;
                }

                bool is_handshake_handle_null()
                {
                    return handshake_handle_ == nullptr;
                }

                bool set_handshake_handle(HandshakeHandle* handshake_handle)
                {
                    if(handshake_handle_ == nullptr)
                    {
                        handshake_handle_ = handshake_handle;
                        return true;
                    }

                    return false;
                }

                HandshakeHandle* get_handshake_handle()
                {
                    HandshakeHandle* handle = handshake_handle_;
                    handshake_handle_ = nullptr;
                    return handle;
                }

                AuthenticationStatus get_auth_status()
                {
                    return auth_status_;
                }

                void set_auth_status(AuthenticationStatus auth_status)
                {
                    auth_status_ = auth_status;
                }

            private:

                DiscoveredParticipantInfo(const DiscoveredParticipantInfo& info) = delete;

                IdentityHandle* identity_handle_;

                HandshakeHandle* handshake_handle_;

                AuthenticationStatus auth_status_;
        };

        void remove_discovered_participant_info(const GUID_t remote_participant_key);
        void restore_remote_identity_handle(const GUID_t& remote_participant_key,
                IdentityHandle* remote_identity_handle);

        bool create_entities();
        void delete_entities();
        bool create_participant_stateless_message_entities();
        void delete_participant_stateless_message_entities();
        bool create_participant_stateless_message_writer();
        void delete_participant_stateless_message_writer();
        bool create_participant_stateless_message_reader();
        void delete_participant_stateless_message_reader();

        bool on_request_not_send(const GUID_t& remote_participant_key, IdentityHandle* remote_identity_handle);

        RTPSParticipantImpl* participant_;
        StatelessWriter* participant_stateless_message_writer_;
        WriterHistory* participant_stateless_message_writer_history_;
        StatelessReader* participant_stateless_message_reader_;
        ReaderHistory* participant_stateless_message_reader_history_;
        SecurityPluginFactory factory_;

        Authentication* authentication_plugin_;

        IdentityHandle* local_identity_handle_;

        std::map<GUID_t, DiscoveredParticipantInfo> discovered_participants_;

        std::mutex mutex_;
        const GUID_t& remote_participant_key,
                const GUID_t& remote_participant_key,
add_subdirectory(unittest/rtps/security)
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file RTPSParticipantImpl.h
 */

#ifndef RTPS_PARTICIPANT_RTPSPARTICIPANTIMPL_H_
#define RTPS_PARTICIPANT_RTPSPARTICIPANTIMPL_H_

#include <fastrtps/rtps/attributes/WriterAttributes.h>
#include <fastrtps/rtps/attributes/ReaderAttributes.h>

#include <gmock/gmock.h>

namespace eprosima {
namespace fastrtps {
namespace rtps {

class RTPSWriter;
class RTPSReader;
class WriterHistory;
class ReaderHistory;
class WriterListener;
class ReaderListener;
class EntityId_t;

class RTPSParticipantImpl
{
    public:

        MOCK_CONST_METHOD0(getRTPSParticipantAttributes, const RTPSParticipantAttributes&());

        MOCK_CONST_METHOD0(getGuid, const GUID_t&());

        MOCK_METHOD6(createWriter, bool (RTPSWriter** Writer, WriterAttributes& param, WriterHistory* hist,WriterListener* listen,
                const EntityId_t& entityId, bool isBuiltin));

        MOCK_METHOD7(createReader, bool (RTPSReader** Reader, ReaderAttributes& param, ReaderHistory* hist,ReaderListener* listen,
                const EntityId_t& entityId, bool isBuiltin, bool enable));
};

} // namespace rtps
} // namespace fastrtps
} // namespace eprosima

#endif // RTPS_PARTICIPANT_RTPSPARTICIPANTIMPL_H_

// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file RTPSReader.h
 */

#ifndef _RTPS_READER_RTPSREADER_H_
#define _RTPS_READER_RTPSREADER_H_

namespace eprosima {
namespace fastrtps {
namespace rtps {

class RTPSReader
{
    public:

        virtual bool matched_writer_add(RemoteWriterAttributes& wdata) = 0;

        virtual bool matched_writer_remove(RemoteWriterAttributes& wdata) = 0;
};

} // namespace rtps
} // namespace fastrtps
} // namespace eprosima

#endif // _RTPS_READER_RTPSREADER_H_
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file RTPSWriter.h
 */

#ifndef _RTPS_WRITER_RTPSWRITER_H_
#define _RTPS_WRITER_RTPSWRITER_H_

namespace eprosima {
namespace fastrtps {
namespace rtps {

class RTPSWriter
{
    public:

        virtual bool matched_reader_add(RemoteReaderAttributes& ratt) = 0;

        virtual bool matched_reader_remove(RemoteReaderAttributes& ratt) = 0;
};

} // namespace rtps
} // namespace fastrtps
} // namespace eprosima

#endif // _RTPS_WRITER_RTPSWRITER_H_
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file ReaderHistory.h
 */

#ifndef _RTPS_HISTORY_READERHISTORY_H_
#define _RTPS_HISTORY_READERHISTORY_H_

#include <fastrtps/rtps/attributes/HistoryAttributes.h>

namespace eprosima {
namespace fastrtps {
namespace rtps {

class ReaderHistory
{
    public:

        ReaderHistory(const HistoryAttributes& /*att*/){}
};

} // namespace rtps
} // namespace fastrtps
} // namespace eprosima

#endif // _RTPS_HISTORY_READERHISTORY_H_
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*!
 * @file MockAuthenticationPlugin.h
 */

#ifndef _SECURITY_MOCKAUTHENTICATIONPLUGIN_H_
#define _SECURITY_MOCKAUTHENTICATIONPLUGIN_H_

// TODO(Ricardo) Change when GMock supports r-values.

#include <fastrtps/rtps/security/authentication/Authentication.h>
#include <gmock/gmock.h>

namespace eprosima {
namespace fastrtps {
namespace rtps {
namespace security {

class MockAuthenticationPlugin : public Authentication
{
    public:

        MOCK_METHOD6(validate_local_identity, ValidationResult_t(IdentityHandle** local_identity_handle,
                GUID_t& adjusted_participant_key,
                const uint32_t domain_id,
                const RTPSParticipantAttributes& participant_attr,
                const GUID_t& candidate_participant_key,
                SecurityException& exception));

        MOCK_METHOD5(validate_remote_identity_rvr, ValidationResult_t(IdentityHandle** remote_identity_handle,
                const IdentityHandle& local_identity_handle,
                IdentityToken remote_identity_token,
                const GUID_t& remote_participant_key,
                SecurityException& exception));

        MOCK_METHOD5(begin_handshake_request, ValidationResult_t(HandshakeHandle** handshake_handle,
                HandshakeMessageToken** handshake_message,
                const IdentityHandle& initiator_identity_handle,
                IdentityHandle& replier_identity_handle,
                SecurityException& exception));

        MOCK_METHOD6(begin_handshake_reply_rvr, ValidationResult_t(HandshakeHandle** handshake_handle,
                HandshakeMessageToken** handshake_message_out,
                HandshakeMessageToken handshake_message_in,
                IdentityHandle& initiator_identity_handle,
                const IdentityHandle& replier_identity_handle,
                SecurityException& exception));

        MOCK_METHOD4(process_handshake_rvr, ValidationResult_t(HandshakeMessageToken** handshake_message_out,
                HandshakeMessageToken handshake_message_in,
                HandshakeHandle& handshake_handle,
                SecurityException& exception));

        MOCK_METHOD2(get_shared_secret, SharedSecretHandle*(const HandshakeHandle& handshake_handle,
                SecurityException& exception));

        MOCK_METHOD2(set_listener, bool(AuthenticationListener* listener,
                SecurityException& exception));

        MOCK_METHOD3(get_identity_token, bool(IdentityToken** identity_token,
                const IdentityHandle& handle,
                SecurityException& exception));

        MOCK_METHOD2(return_identity_token, bool(IdentityToken* token,
                SecurityException& exception));

        MOCK_METHOD2(return_handshake_handle, bool(HandshakeHandle* handshake_handle,
                SecurityException& exception));

        MOCK_METHOD2(return_identity_handle, bool(IdentityHandle* identity_handle,
                SecurityException& exception));

        MOCK_METHOD2(return_sharedsecret_handle, bool(SharedSecretHandle* sharedsecret_handle,
                SecurityException& exception));

        ValidationResult_t validate_remote_identity(IdentityHandle** remote_identity_handle,
                const IdentityHandle& local_identity_handle,
                IdentityToken&& remote_identity_token,
                const GUID_t& remote_participant_key,
                SecurityException& exception)
        {
            return validate_remote_identity_rvr(remote_identity_handle, local_identity_handle,
                    remote_identity_token, remote_participant_key, exception);
        }

        ValidationResult_t begin_handshake_reply(HandshakeHandle** handshake_handle,
                HandshakeMessageToken** handshake_message_out,
                HandshakeMessageToken&& handshake_message_in,
                IdentityHandle& initiator_identity_handle,
                const IdentityHandle& replier_identity_handle,
                SecurityException& exception)
        {
            return begin_handshake_reply_rvr(handshake_handle, handshake_message_out, handshake_message_in,
                    initiator_identity_handle, replier_identity_handle, exception);
        }

        ValidationResult_t process_handshake(HandshakeMessageToken** handshake_message_out,
                HandshakeMessageToken&& handshake_message_in,
                HandshakeHandle& handshake_handle,
                SecurityException& exception)
        {
            return process_handshake_rvr(handshake_message_out, handshake_message_in,
                    handshake_handle, exception);
        }
};

} // namespace security
} // namespace rtps
} // namespace fastrtps
} // namespace eprosima

#endif // _SECURITY_MOCKAUTHENTICATIONPLUGIN_H_
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*!
 * @file SecurityPluginFactory.cpp
 */

#include "SecurityPluginFactory.h"

using namespace eprosima::fastrtps::rtps;
using namespace ::security;

Authentication* SecurityPluginFactory::auth_plugin_ = nullptr;

Authentication* SecurityPluginFactory::create_authentication_plugin(const PropertyPolicy& /*property_policy*/)
{
    return auth_plugin_;
}

void SecurityPluginFactory::set_auth_plugin(Authentication* plugin)
{
    auth_plugin_ = plugin;
}

void SecurityPluginFactory::release_auth_plugin()
{
    auth_plugin_ = nullptr;
}
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*!
 * @file SecurityPluginFactory.h
 */
#ifndef _RTPS_SECURITY_SECURITYPLUGINFACTORY_H_
#define _RTPS_SECURITY_SECURITYPLUGINFACTORY_H_

#include <fastrtps/rtps/security/authentication/Authentication.h>
#include <fastrtps/rtps/attributes/PropertyPolicy.h>

namespace eprosima {
namespace fastrtps {
namespace rtps {
namespace security {

class SecurityPluginFactory
{
    public:

        /*!
         * @brief Create an Authentication plugin  described in the PropertyPolicy.
         * @param property_policy PropertyPolicy containing the definition of the Authentication
         * plugin that has to be created.
         * @param Pointer to the new Authentication plugin. In case of error nullptr will be returned.
         */
        Authentication* create_authentication_plugin(const PropertyPolicy& property_policy);

        static void set_auth_plugin(Authentication* plugin);

        static void release_auth_plugin();

    private:

        static Authentication* auth_plugin_;
};

} //namespace security
} //namespace rtps
} //namespace fastrtps
} //namespace eprosima

#endif // _RTPS_SECURITY_SECURITYPLUGINFACTORY_H_
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file StatelessReader.h
 */

#ifndef _RTPS_READER_STATELESSREADER_H_
#define _RTPS_READER_STATELESSREADER_H_

#include <fastrtps/rtps/reader/RTPSReader.h>

namespace eprosima {
namespace fastrtps {
namespace rtps {

class StatelessReader : public RTPSReader
{
    public:

        MOCK_METHOD1(matched_writer_add, bool(RemoteWriterAttributes&));

        MOCK_METHOD1(matched_writer_remove, bool(RemoteWriterAttributes&));
};

} // namespace rtps
} // namespace fastrtps
} // namespace eprosima

#endif // _RTPS_READER_STATELESSREADER_H_
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file StatelessWriter.h
 */

#ifndef _RTPS_WRITER_STATELESSWRITER_H_
#define _RTPS_WRITER_STATELESSWRITER_H_

#include <fastrtps/rtps/writer/RTPSWriter.h>

namespace eprosima {
namespace fastrtps {
namespace rtps {

class StatelessWriter : public RTPSWriter
{
    public:

        MOCK_METHOD1(matched_reader_add, bool(RemoteReaderAttributes&));

        MOCK_METHOD1(matched_reader_remove, bool(RemoteReaderAttributes&));
};

} // namespace rtps
} // namespace fastrtps
} // namespace eprosima

#endif // _RTPS_WRITER_STATELESSWRITER_H_
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file WriterHistory.h
 */

#ifndef _RTPS_HISTORY_WRITERHISTORY_H_
#define _RTPS_HISTORY_WRITERHISTORY_H_

#include <fastrtps/rtps/attributes/HistoryAttributes.h>

namespace eprosima {
namespace fastrtps {
namespace rtps {

class WriterHistory
{
    public:


        WriterHistory(const HistoryAttributes& /*att*/){}
};

} // namespace rtps
} // namespace fastrtps
} // namespace eprosima

#endif // _RTPS_HISTORY_WRITERHISTORY_H_
# Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER))
    include(${PROJECT_SOURCE_DIR}/cmake/dev/gtest.cmake)
    check_gtest()
    check_gmock()

    if(GTEST_FOUND AND GMOCK_FOUND)
        if(WIN32)
            add_definitions(-D_WIN32_WINNT=0x0601)
        endif()

        set(SOURCES_SECURITY_TEST_SOURCE
            ${PROJECT_SOURCE_DIR}/src/cpp/log/Log.cpp
            ${PROJECT_SOURCE_DIR}/src/cpp/log/StdoutConsumer.cpp
            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/attributes/PropertyPolicy.cpp
            ${PROJECT_SOURCE_DIR}/test/mock/rtps/SecurityPluginFactory/SecurityPluginFactory.cpp
            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/SecurityManager.cpp
            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/exceptions/Exception.cpp
            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security/exceptions/SecurityException.cpp
            )

        add_executable(SecurityAuthentication ${SOURCES_SECURITY_TEST_SOURCE}
            ${CMAKE_CURRENT_SOURCE_DIR}/SecurityAuthenticationTests.cpp)
        add_gtest(SecurityAuthentication 
            ${CMAKE_CURRENT_SOURCE_DIR}/SecurityAuthenticationTests.cpp)
        target_include_directories(SecurityAuthentication PRIVATE
            ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS}
            ${PROJECT_SOURCE_DIR}/test/mock/rtps/SecurityPluginFactory
            ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSParticipantImpl
            ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSWriter
            ${PROJECT_SOURCE_DIR}/test/mock/rtps/StatelessWriter
            ${PROJECT_SOURCE_DIR}/test/mock/rtps/WriterHistory
            ${PROJECT_SOURCE_DIR}/test/mock/rtps/RTPSReader
            ${PROJECT_SOURCE_DIR}/test/mock/rtps/StatelessReader
            ${PROJECT_SOURCE_DIR}/test/mock/rtps/ReaderHistory
            ${PROJECT_SOURCE_DIR}/src/cpp/rtps/security
            ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include/${PROJECT_NAME})
        target_link_libraries(SecurityAuthentication ${Boost_LIBRARIES} ${GMOCK_LIBRARIES})
    endif()
endif()
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <fastrtps/rtps/security/common/Handle.h>
#include <MockAuthenticationPlugin.h>
#include <rtps/participant/RTPSParticipantImpl.h>
#include <SecurityPluginFactory.h>
#include <SecurityManager.h>

#include <gtest/gtest.h>

using namespace eprosima::fastrtps::rtps;
using namespace ::security;
using namespace ::testing;

using ::testing::DefaultValue;

class MockIdentity
{
    public:

        static const char* const class_id_;
};

const char* const MockIdentity::class_id_ = "MockIdentityHandle";

typedef HandleImpl<MockIdentity> MockIdentityHandle;

class MockHandshake
{
    public:

        static const char* const class_id_;
};

const char* const MockHandshake::class_id_ = "MockHandshakeHandle";

typedef HandleImpl<MockHandshake> MockHandshakeHandle;

// Default Values
RTPSParticipantAttributes pattr;
GUID_t guid;

class SecurityAuthenticationTest : public ::testing::Test
{
    protected:

        virtual void SetUp()
        {
            SecurityPluginFactory::set_auth_plugin(auth_plugin_);
        }

        virtual void TearDown()
        {
            SecurityPluginFactory::release_auth_plugin();
        }

        void initialization_ok()
        {
            DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
            DefaultValue<const GUID_t&>::Set(guid);
            MockIdentityHandle identity_handle;
            MockIdentityHandle* p_identity_handle = &identity_handle;

            EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(1).
                WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));
            EXPECT_CALL(participant_, createWriter(_,_,_,_,_,_)).Times(1).
                WillOnce(Return(true));
            EXPECT_CALL(participant_, createReader(_,_,_,_,_,_,_)).Times(1).
                WillOnce(Return(true));

            ASSERT_TRUE(manager_.init());
        }


    public:

        SecurityAuthenticationTest() : auth_plugin_(new MockAuthenticationPlugin()), manager_(&participant_) {}
        MockAuthenticationPlugin* auth_plugin_;
        NiceMock<RTPSParticipantImpl> participant_;
        SecurityManager manager_;
};

TEST_F(SecurityAuthenticationTest, initialization_auth_nullptr)
{
    SecurityPluginFactory::release_auth_plugin();
    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
    DefaultValue<const GUID_t&>::Set(guid);

    ASSERT_FALSE(manager_.init());
}

TEST_F(SecurityAuthenticationTest, initialization_auth_failed)
{
    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
    DefaultValue<const GUID_t&>::Set(guid);

    EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(1).
        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));

    ASSERT_FALSE(manager_.init());
}

TEST_F(SecurityAuthenticationTest, initialization_fail_participant_stateless_message_writer)
{
    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
    DefaultValue<const GUID_t&>::Set(guid);
    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;

    EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));
    EXPECT_CALL(participant_, createWriter(_,_,_,_,_,_)).Times(1).
        WillOnce(Return(false));

    ASSERT_FALSE(manager_.init());
}

TEST_F(SecurityAuthenticationTest, initialization_fail_participant_stateless_message_reader)
{
    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
    DefaultValue<const GUID_t&>::Set(guid);
    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;

    EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));
    EXPECT_CALL(participant_, createWriter(_,_,_,_,_,_)).Times(1).
        WillOnce(Return(true));
    EXPECT_CALL(participant_, createReader(_,_,_,_,_,_,_)).Times(1).
        WillOnce(Return(false));

    ASSERT_FALSE(manager_.init());
}

TEST_F(SecurityAuthenticationTest, initialization_auth_retry)
{
    DefaultValue<const RTPSParticipantAttributes&>::Set(pattr);
    DefaultValue<const GUID_t&>::Set(guid);
    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;

    EXPECT_CALL(*auth_plugin_, validate_local_identity(_,_,_,_,_,_)).Times(2).
        WillOnce(Return(ValidationResult_t::VALIDATION_PENDING_RETRY)).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));
    EXPECT_CALL(participant_, createWriter(_,_,_,_,_,_)).Times(1).
        WillOnce(Return(true));
    EXPECT_CALL(participant_, createReader(_,_,_,_,_,_,_)).Times(1).
        WillOnce(Return(true));

    ASSERT_TRUE(manager_.init());
}


TEST_F(SecurityAuthenticationTest, initialization_ok)
{
    initialization_ok();
}

TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_fail)
{
    initialization_ok();

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));

    GUID_t remote_participant_key;
    ASSERT_FALSE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
}

TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_ok)
{
    initialization_ok();

    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_OK)));

    GUID_t remote_participant_key;
    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
}

TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_pending_handshake_message)
{
    initialization_ok();

    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_MESSAGE)));

    GUID_t remote_participant_key;
    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
}

TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_pending_handshake_request_fail)
{
    initialization_ok();

    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));

    GUID_t remote_participant_key;
    ASSERT_FALSE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
}

TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_pending_handshake_request_ok)
{
    initialization_ok();

    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;
    MockHandshakeHandle handshake_handle;
    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_OK)));

    GUID_t remote_participant_key;
    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
}

TEST_F(SecurityAuthenticationTest, discovered_participant_validation_remote_identity_pending_handshake_request_ok_with_final_message)
{
    initialization_ok();

    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;
    MockHandshakeHandle handshake_handle;
    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_OK_WITH_FINAL_MESSAGE)));

    GUID_t remote_participant_key;
    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
}

TEST_F(SecurityAuthenticationTest, discovered_participant_ok)
{
    initialization_ok();

    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;
    MockHandshakeHandle handshake_handle;
    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_MESSAGE)));

    GUID_t remote_participant_key;
    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
}

TEST_F(SecurityAuthenticationTest, discovered_participant_validate_remote_fail_and_then_ok)
{
    initialization_ok();

    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;
    MockHandshakeHandle handshake_handle;
    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));

    GUID_t remote_participant_key;
    ASSERT_FALSE(manager_.discovered_participant(IdentityToken(), remote_participant_key));

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_MESSAGE)));

    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
}

TEST_F(SecurityAuthenticationTest, discovered_participant_begin_handshake_request_fail_and_then_ok)
{
    initialization_ok();

    MockIdentityHandle identity_handle;
    MockIdentityHandle* p_identity_handle = &identity_handle;
    MockHandshakeHandle handshake_handle;
    MockHandshakeHandle* p_handshake_handle = &handshake_handle;
    HandshakeMessageToken* p_handshake_message = new HandshakeMessageToken();

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_identity_handle), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_REQUEST)));
    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
        WillOnce(Return(ValidationResult_t::VALIDATION_FAILED));

    GUID_t remote_participant_key;
    ASSERT_FALSE(manager_.discovered_participant(IdentityToken(), remote_participant_key));

    EXPECT_CALL(*auth_plugin_, validate_remote_identity_rvr(_,_,_,_,_)).Times(0);
    EXPECT_CALL(*auth_plugin_, begin_handshake_request(_,_,_,_,_)).Times(1).
        WillOnce(DoAll(SetArgPointee<0>(p_handshake_handle), 
                    SetArgPointee<1>(p_handshake_message), Return(ValidationResult_t::VALIDATION_PENDING_HANDSHAKE_MESSAGE)));

    ASSERT_TRUE(manager_.discovered_participant(IdentityToken(), remote_participant_key));
}

int main(int argc, char **argv)
{
    testing::InitGoogleMock(&argc, argv);
    return RUN_ALL_TESTS();
}