PLCnext API Documentation  20.0.0.24462
TlsSocket.hpp
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
8 #include "Arp/System/Commons/Net/IpAddress.hpp"
9 #include "Arp/System/Commons/Net/Socket.hpp"
10 #include "Arp/System/Commons/Logging.h"
11 #include "Arp/System/Commons/Exceptions/Exceptions.h"
12 #include "Arp/System/Commons/Security/IdentityStore.hpp"
13 
14 using namespace Arp::System::Commons::Security;
15 
16 // forwards
17 typedef struct ssl_st SSL;
18 typedef struct ssl_ctx_st SSL_CTX;
19 
20 namespace Arp { namespace System { namespace Commons { namespace Net
21 {
22 
30 
31 class TlsSocket : private Loggable<TlsSocket>
32 {
33 private: // nested class TlsContext
34  class TlsContext
35  {
36  public:
37  using Ptr = shared_ptr<TlsContext>;
38 
39  // construction/destruction
40  TlsContext(void);
41  TlsContext(const TlsContext& arg) = delete;
42  ~TlsContext(void);
43 
44  public: //operations
45  TlsContext& operator=(const TlsContext& arg) = delete;
46 
47  public: // Properties
48  SSL_CTX* pTlsCtx = nullptr;
49  };
50 
51 
52 
53 
54  friend class TlsContext;
55 
56 public: // typedefs/usings
57 
59  typedef std::shared_ptr<TlsSocket> Ptr;
60 
62  using ISocketService = Arp::System::Ve::ISocketService;
63 
64 public: // construction/destruction
65 
71  TlsSocket(SocketType type, SocketDomain domain, SocketBlockingMode blockingMode);
72 
74  TlsSocket(const TlsSocket& arg) = delete;
75 
77  TlsSocket& operator=(const TlsSocket& arg) = delete;
78 
82  ~TlsSocket(void);
83 
84 private: // construction
85  TlsSocket(Socket::Ptr pSocket, TlsContext::Ptr pContext, bool isInitialized);
86 
87 public: // operators
88 
89 public: // static operations
90 
91 public: // setter/getter operations
92 
96  SocketType GetSocketType(void);
97 
101  SocketDomain GetSocketDomain(void);
102 
106  bool IsBlocking(void);
107 
111  bool IsConnected(void);
112 
116  bool IsTlsConnected(void);
117 
121  IpAddress GetRemoteIpAddress(void);
122 
128  int GetRemotePort(void);
129 
130 public: // operations
131 
149  Ptr Accept(IpAddress& ip4address, int& port, SocketError& error);
150 
162  SocketError Bind(const IpAddress& ip4Address, int port);
163 
175  SocketError Listen(size_t backlog);
176 
186  SocketError Connect(const IpAddress& ip4Address, int port);
187 
193  SocketError Shutdown(void);
194 
198  SocketError Close(void);
199 
207  int Send(const void* pBuffer, size_t length, SocketError& error);
208 
216  int Receive(void* pBuffer, size_t length, SocketError& error);
217 
226  bool Select(SelectMode mode, Microseconds timeout, SocketError& error);
227 
235  SocketError SetSocketOption(SocketOptionName optionName, const void* optionValue, size_t optionLength);
236 
245  SocketError GetSocketOption(SocketOptionName optionName, void* optionValue, size_t *optionLength);
246 
257  SocketError SetOptionReuseAddress(bool enabled);
258 
266  SocketError GetOptionReuseAddress(bool& enabled);
267 
278  SocketError SetOptionKeepAlive(bool enabled);
279 
287  SocketError GetOptionKeepAlive(bool& enabled);
288 
297  SocketError SetOptionBroadcast(bool enabled);
298 
306  SocketError GetOptionBroadcast(bool& enabled);
307 
317  SocketError SetOptionNoDelay(bool enabled);
318 
326  SocketError GetOptionNoDelay(bool& enabled);
327 
343  SocketError SetOptionLinger(bool enable, size_t timeout);
344 
351  SocketError GetOptionLinger(bool& enable, size_t& timeout);
352 
356  SocketError SetOptionBlocking(bool enable);
357 
375  SocketError InitClient(const String& trustStoreName, const String& identityStoreName, const String& hostName);
376 
388  SocketError InitServer(const String& identityStoreName, const String& trustStoreName = "");
389 
398  void SetCipherList(String cipherList);
399 
400 protected: // operations
401 
402 private: // static methods
403 
404 private: // methods
405  Ptr TcpAccept(IpAddress& ip4address, int& port, SocketError& error);
406  SocketError TlsAccept(void);
407  SocketError TcpConnect(const IpAddress& ipAddress, int port);
408  SocketError TlsConnect(void);
409  SocketError HandleSslResult(int result, int* sslErrorOut = nullptr);
410  int GetFileDescriptor(void);
411  void ClearOpenSslErrors(void);
412 
413 private: // fields
414  Socket::Ptr pSocket = nullptr;
415  SSL* sslConnection = nullptr;
416  TlsContext::Ptr pContext;
417 
418  Ptr currentAcceptSocket;
419 
420  bool tlsIsConnected; //true if TLS Handshake was completed
421  bool hasSslError;
422  bool socketIsConnected; //true if tcp socket is connected / accepted (set before SSL_connect / SSL_accept)
423  bool tlsInitDone;
424  bool isInitialized; // true if InitClient resp. InitServer has already been called
425  bool tlsConnectIsPending;
426  bool pendingTlsConnectNeedsRead;
427 
428  String hostNameToVerify;
429 };
430 
432 // inline methods of class Socket
433 
434 inline SocketType TlsSocket::GetSocketType(void)
435 {
436  return this->pSocket->GetSocketType();
437 }
438 
439 inline SocketDomain TlsSocket::GetSocketDomain(void)
440 {
441  return this->pSocket->GetSocketDomain();
442 }
443 
444 inline bool TlsSocket::IsBlocking(void)
445 {
446  return this->pSocket->IsBlocking();
447 }
448 
449 inline IpAddress TlsSocket::GetRemoteIpAddress(void)
450 {
451  return this->pSocket->GetRemoteIpAddress();
452 }
453 
454 inline int TlsSocket::GetRemotePort(void)
455 {
456  return this->pSocket->GetRemotePort();
457 }
458 
459 inline bool TlsSocket::IsConnected(void)
460 {
461  return (!this->hasSslError) && (this->tlsIsConnected || this->socketIsConnected);
462 }
463 
464 inline bool TlsSocket::IsTlsConnected(void)
465 {
466  return (!this->hasSslError) && (this->tlsIsConnected);
467 }
468 
469 inline SocketError TlsSocket::Bind(const IpAddress& ip4Address, int port)
470 {
471  return pSocket->Bind(ip4Address, port);
472 }
473 
474 inline SocketError TlsSocket::Listen(size_t backlog)
475 {
476  return pSocket->Listen(backlog);
477 }
478 
479 inline SocketError TlsSocket::SetSocketOption(SocketOptionName optionName, const void * optionValue, size_t optionLength)
480 {
481  return this->pSocket->SetSocketOption(optionName, optionValue, optionLength);
482 }
483 
484 inline SocketError TlsSocket::GetSocketOption(SocketOptionName optionName, void * optionValue, size_t * optionLength)
485 {
486  return this->pSocket->GetSocketOption(optionName, optionValue, optionLength);
487 }
488 
489 inline SocketError TlsSocket::SetOptionReuseAddress(bool enabled)
490 {
491  return this->pSocket->SetOptionReuseAddress(enabled);
492 }
493 
494 inline SocketError TlsSocket::GetOptionReuseAddress(bool& enabled)
495 {
496  return this->pSocket->GetOptionReuseAddress(enabled);
497 }
498 
499 inline SocketError TlsSocket::SetOptionKeepAlive(bool enabled)
500 {
501  return this->pSocket->SetOptionKeepAlive(enabled);
502 }
503 
504 inline SocketError TlsSocket::GetOptionKeepAlive(bool& enabled)
505 {
506  return this->pSocket->GetOptionKeepAlive(enabled);
507 }
508 
509 inline SocketError TlsSocket::SetOptionBroadcast(bool enabled)
510 {
511  return this->pSocket->SetOptionBroadcast(enabled);
512 }
513 
514 inline SocketError TlsSocket::GetOptionBroadcast(bool& enabled)
515 {
516  return this->pSocket->GetOptionBroadcast(enabled);
517 }
518 
519 inline SocketError TlsSocket::SetOptionNoDelay(bool enabled)
520 {
521  return this->pSocket->SetOptionNoDelay(enabled);
522 }
523 
524 inline SocketError TlsSocket::GetOptionNoDelay(bool& enabled)
525 {
526  return this->pSocket->GetOptionNoDelay(enabled);
527 }
528 
529 inline SocketError TlsSocket::SetOptionLinger(bool enable, size_t timeout)
530 {
531  return this->pSocket->SetOptionLinger(enable, timeout);
532 }
533 
534 inline SocketError TlsSocket::GetOptionLinger(bool& enable, size_t& timeout)
535 {
536  return this->pSocket->GetOptionLinger(enable, timeout);
537 }
538 
539 inline SocketError TlsSocket::SetOptionBlocking(bool enable)
540 {
541  return this->pSocket->SetOptionBlocking(enable);
542 }
543 
544 }}}} // end of namespace Arp::System::Commons::Net
SocketType
Enumeration of supported socket types.
Definition: SocketType.hpp:13
SocketError
Possible error codes for socket operation results.
Definition: SocketError.hpp:14
Check if a connect request can be performed.
SocketOptionName
Specifies socket options to be set by the application. Copied from Eclr Socket Adaption ...
Definition: SocketOptionName.hpp:16
Arp::System::Ve::ISocketService ISocketService
Injection of SocketService-Interface in class context.
Definition: TlsSocket.hpp:62
A connect request was made on an already connected socket.
std::shared_ptr< TlsSocket > Ptr
Contextual definition of pointer type.
Definition: TlsSocket.hpp:59
Namespace for classes dealing with certificates
std::chrono::microseconds Microseconds
The Arp Microseconds unit class.
Definition: TypeSystem.h:34
std::shared_ptr< Socket > Ptr
Contextual definition of pointer type.
Definition: Socket.hpp:120
SocketDomain
Supported communication domains, selecting the protocol for communication.
Definition: SocketDomain.hpp:13
Root namespace for the PLCnext API
SocketBlockingMode
Supported blocking modes.
Definition: Socket.hpp:25
Check if a connection request is pending.
A request to send or receive data was disallowed because the socket had already been shut down in tha...
SelectMode
Modes for Select call to check different data channels.
Definition: SelectMode.hpp:13
Unified representation for ip address schemes.
Definition: IpAddress.hpp:13
System components used by the System, Device, Plc or Io domains.
Interface to realize TLS Connection over TCP
Definition: TlsSocket.hpp:31