Skip to content

Commit

Permalink
Merge pull request #1806 from rdkcentral/development/SecureSockets
Browse files Browse the repository at this point in the history
* [SSL] Integrate OpenSSL behind C++ wrappers for Key/Certificate and a Certificate Store.

Client code:
class WebClient : public Web::WebLinkType<Crypto::SecureSocketPort, Web::Response, Web::Request, WPEFramework::Core::ProxyPoolType<Web::Response>&> {
   ...
}

WebClient webConnector(Core::NodeId("catfact.ninja", 443));

webConnector.Link().Root(Crypto::CertificateStore::Default());

uint32_t result = webConnector.Open(10000);

if (result != Core::ERROR_NONE) {
    printf("Could not open the connection, error: %d\n", result);
}
else {

    printf("Waiting for a number of seconds for the result!\n");
    SleepMs(5000);

    printf("The answer should be in by now, lets close it!\n");
    webConnector.Close(100)
}

Server/Client code:
void OpeningSecuredServerPort()
{
    Crypto::Certificate certificate(_T("D:/domotica/src/ca_certficates/onsite.crt"));
    Crypto::Key key(_T("D:/domotica/src/ca_certficates/onsite.key"), _T(""));

    Crypto::Certificate CA(_T("D:/domotica/src/ca_certficates/rootCA.pem"));
    Crypto::CertificateStore store;
    store.Add(CA);

    const Core::NodeId localNode(localHostName, tcpServerPort, Core::NodeId::TYPE_IPV4);

    // This is a listening socket as result of using SocketServerType which enables listening
    Crypto::SecureSocketServerType<WebSocketServer<SecureStream, sendBufferSize, receiveBufferSize>> server(certificate, key, localNode /* listening node*/);

    if (server.Open(maxWaitTimeMs) == Core::ERROR_NONE) {

        // Time to open a Client, see if I can get some data :-)
        WebSocketClient<SecureStream> client(webSocketURIPath, webSocketProtocol, webSocketURIQuery, webSocketOrigin, false, true, rawSocket, localNode.AnyInterface(), localNode, sendBufferSize, receiveBufferSize, "WebSocketClient");

        client.Link().Root(store);

        if (client.Open(3000) == Core::ERROR_NONE) {
            std::basic_string<uint8_t> message(request, sizeof(request));
            // Seems we have connections, now exchange a message
            client.Submit(message);

            // Sleep for some time so we can send and receive it :-)
            SleepMs(1000);

            WebSocketClient<SecureStream>::Message response = client.Response();

            printf("%s\n\n", response.c_str());

            client.Close(Core::infinite);
        }
    }
}

* [REFACTOR] The constructors are fixed, use them fixed.
  • Loading branch information
pwielders authored Dec 11, 2024
2 parents 50273c5 + 6e92ffd commit 5ede424
Show file tree
Hide file tree
Showing 3 changed files with 586 additions and 202 deletions.
47 changes: 21 additions & 26 deletions Source/core/SocketServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace Core {
template <typename CLIENT>
class SocketServerType {
private:
typedef std::map<uint32_t, Core::ProxyType<CLIENT>> ClientMap;
using ClientMap = std::map<uint32_t, Core::ProxyType<CLIENT>>;

public:
template <typename HANDLECLIENT>
Expand Down Expand Up @@ -69,9 +69,7 @@ namespace Core {
{
move._atHead = true;
}
~IteratorType()
{
}
~IteratorType() = default;

IteratorType& operator=(const IteratorType<HANDLECLIENT>& RHS)
{
Expand Down Expand Up @@ -130,38 +128,35 @@ namespace Core {
typename std::list<HANDLECLIENT>::iterator _iterator;
};

typedef IteratorType<ProxyType<CLIENT>> Iterator;
using Iterator = IteratorType<ProxyType<CLIENT>>;

private:
template <typename HANDLECLIENT>
class SocketHandler : public SocketListner {
private:
public:
SocketHandler() = delete;
SocketHandler(SocketHandler<HANDLECLIENT>&&) = delete;
SocketHandler(const SocketHandler<HANDLECLIENT>&) = delete;
SocketHandler<HANDLECLIENT>& operator=(SocketHandler<HANDLECLIENT>&&) = delete;
SocketHandler<HANDLECLIENT>& operator=(const SocketHandler<HANDLECLIENT>&) = delete;

public:
SocketHandler(SocketServerType<CLIENT>* parent)
SocketHandler(SocketServerType<CLIENT>& parent)
: SocketListner()
, _nextClient(1)
, _lock()
, _clients()
, _parent(*parent)
, _parent(parent)
{

ASSERT(parent != nullptr);
}
SocketHandler(const NodeId& listenNode, SocketServerType<CLIENT>* parent)
SocketHandler(const NodeId& listenNode, SocketServerType<CLIENT>& parent)
: SocketListner(listenNode)
, _nextClient(1)
, _lock()
, _clients()
, _parent(*parent)
, _parent(parent)
{

ASSERT(parent != nullptr);
}
~SocketHandler()
~SocketHandler() override
{
SocketListner::Close(Core::infinite);
CloseClients(0);
Expand Down Expand Up @@ -267,7 +262,7 @@ namespace Core {
// Do not change the Close() duration to a value >0. We should just test, but not wait for a statechange.
// Waiting for a Statwchange might require, in the SocketPort imlementation of Close, WaitForCloseure with
// parameter Core::infinite in case we have a faulthy socket. This call will than only return if the
// ResourceMonitor thread does report on CLosure of the socket. However, the ResourceMonitor thread might
// ResourceMonitor thread does report on Closure of the socket. However, the ResourceMonitor thread might
// also be calling into here for an Accept.
// In that case, the Accept will block on the _lock from this object as it is taken by this Cleanup call
// running on a different thread but also this lock will not be freed as this cleanup thread is waiting
Expand All @@ -286,7 +281,7 @@ namespace Core {

_lock.Unlock();
}
virtual void Accept(SOCKET& newClient, const NodeId& remoteId)
void Accept(SOCKET& newClient, const NodeId& remoteId) override
{
ProxyType<HANDLECLIENT> client = ProxyType<HANDLECLIENT>::Create(newClient, remoteId, &_parent);

Expand Down Expand Up @@ -353,23 +348,23 @@ namespace Core {
SocketServerType<CLIENT>& _parent;
};

public:
SocketServerType(SocketServerType<CLIENT>&&) = delete;
SocketServerType(const SocketServerType<CLIENT>&) = delete;
SocketServerType<CLIENT>& operator=(SocketServerType<CLIENT>&&) = delete;
SocketServerType<CLIENT>& operator=(const SocketServerType<CLIENT>&) = delete;

public:
PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST)
PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST)
SocketServerType()
: _handler(this)
: _handler(*this)
{
}
SocketServerType(const NodeId& listeningNode)
: _handler(listeningNode, this)
{
}
POP_WARNING()
~SocketServerType()
: _handler(listeningNode, *this)
{
}
POP_WARNING()
~SocketServerType() = default;

public:
inline uint32_t Open(const uint32_t waitTime)
Expand Down
Loading

0 comments on commit 5ede424

Please sign in to comment.