PLCnext API Documentation  21.0.0.35466
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 
178  SocketError Bind2(const IpAddress& ip4Address, int& port);
179 
191  SocketError Listen(size_t backlog);
192 
202  SocketError Connect(const IpAddress& ip4Address, int port);
203 
209  SocketError Shutdown(void);
210 
214  SocketError Close(void);
215 
223  int Send(const void* pBuffer, size_t length, SocketError& error);
224 
232  int Receive(void* pBuffer, size_t length, SocketError& error);
233 
242  bool Select(SelectMode mode, Microseconds timeout, SocketError& error);
243 
251  SocketError SetSocketOption(SocketOptionName optionName, const void* optionValue, size_t optionLength);
252 
261  SocketError GetSocketOption(SocketOptionName optionName, void* optionValue, size_t *optionLength);
262 
273  SocketError SetOptionReuseAddress(bool enabled);
274 
282  SocketError GetOptionReuseAddress(bool& enabled);
283 
294  SocketError SetOptionKeepAlive(bool enabled);
295 
303  SocketError GetOptionKeepAlive(bool& enabled);
304 
313  SocketError SetOptionBroadcast(bool enabled);
314 
322  SocketError GetOptionBroadcast(bool& enabled);
323 
333  SocketError SetOptionNoDelay(bool enabled);
334 
342  SocketError GetOptionNoDelay(bool& enabled);
343 
359  SocketError SetOptionLinger(bool enable, size_t timeout);
360 
367  SocketError GetOptionLinger(bool& enable, size_t& timeout);
368 
372  SocketError SetOptionBlocking(bool enable);
373 
391  SocketError InitClient(const String& trustStoreName, const String& identityStoreName, const String& hostName);
392 
404  SocketError InitServer(const String& identityStoreName, const String& trustStoreName = "");
405 
414  void SetCipherList(String cipherList);
415 
416 protected: // operations
417 
418 private: // static methods
419 
420 private: // methods
421  Ptr TcpAccept(IpAddress& ip4address, int& port, SocketError& error);
422  SocketError TlsAccept(void);
423  SocketError TcpConnect(const IpAddress& ipAddress, int port);
424  SocketError TlsConnect(void);
425  SocketError HandleSslResult(int result, int* sslErrorOut = nullptr);
426  int GetFileDescriptor(void);
427  void ClearOpenSslErrors(void);
428 
429 private: // fields
430  Socket::Ptr pSocket = nullptr;
431  SSL* sslConnection = nullptr;
432  TlsContext::Ptr pContext;
433 
434  Ptr currentAcceptSocket;
435 
436  bool tlsIsConnected; //true if TLS Handshake was completed
437  bool hasSslError;
438  bool socketIsConnected; //true if tcp socket is connected / accepted (set before SSL_connect / SSL_accept)
439  bool tlsInitDone;
440  bool isInitialized; // true if InitClient resp. InitServer has already been called
441  bool tlsConnectIsPending;
442  bool pendingTlsConnectNeedsRead;
443 
444  String hostNameToVerify;
445 };
446 
448 // inline methods of class Socket
449 
450 inline SocketType TlsSocket::GetSocketType(void)
451 {
452  return this->pSocket->GetSocketType();
453 }
454 
455 inline SocketDomain TlsSocket::GetSocketDomain(void)
456 {
457  return this->pSocket->GetSocketDomain();
458 }
459 
460 inline bool TlsSocket::IsBlocking(void)
461 {
462  return this->pSocket->IsBlocking();
463 }
464 
465 inline IpAddress TlsSocket::GetRemoteIpAddress(void)
466 {
467  return this->pSocket->GetRemoteIpAddress();
468 }
469 
470 inline int TlsSocket::GetRemotePort(void)
471 {
472  return this->pSocket->GetRemotePort();
473 }
474 
475 inline bool TlsSocket::IsConnected(void)
476 {
477  return (!this->hasSslError) && (this->tlsIsConnected || this->socketIsConnected);
478 }
479 
480 inline bool TlsSocket::IsTlsConnected(void)
481 {
482  return (!this->hasSslError) && (this->tlsIsConnected);
483 }
484 
485 inline SocketError TlsSocket::Bind(const IpAddress& ip4Address, int port)
486 {
487  return pSocket->Bind(ip4Address, port);
488 }
489 
490 inline SocketError TlsSocket::Bind2(const IpAddress& ip4Address, int& port)
491 {
492  return pSocket->Bind2(ip4Address, port);
493 }
494 
495 
496 inline SocketError TlsSocket::Listen(size_t backlog)
497 {
498  return pSocket->Listen(backlog);
499 }
500 
501 inline SocketError TlsSocket::SetSocketOption(SocketOptionName optionName, const void * optionValue, size_t optionLength)
502 {
503  return this->pSocket->SetSocketOption(optionName, optionValue, optionLength);
504 }
505 
506 inline SocketError TlsSocket::GetSocketOption(SocketOptionName optionName, void * optionValue, size_t * optionLength)
507 {
508  return this->pSocket->GetSocketOption(optionName, optionValue, optionLength);
509 }
510 
511 inline SocketError TlsSocket::SetOptionReuseAddress(bool enabled)
512 {
513  return this->pSocket->SetOptionReuseAddress(enabled);
514 }
515 
516 inline SocketError TlsSocket::GetOptionReuseAddress(bool& enabled)
517 {
518  return this->pSocket->GetOptionReuseAddress(enabled);
519 }
520 
521 inline SocketError TlsSocket::SetOptionKeepAlive(bool enabled)
522 {
523  return this->pSocket->SetOptionKeepAlive(enabled);
524 }
525 
526 inline SocketError TlsSocket::GetOptionKeepAlive(bool& enabled)
527 {
528  return this->pSocket->GetOptionKeepAlive(enabled);
529 }
530 
531 inline SocketError TlsSocket::SetOptionBroadcast(bool enabled)
532 {
533  return this->pSocket->SetOptionBroadcast(enabled);
534 }
535 
536 inline SocketError TlsSocket::GetOptionBroadcast(bool& enabled)
537 {
538  return this->pSocket->GetOptionBroadcast(enabled);
539 }
540 
541 inline SocketError TlsSocket::SetOptionNoDelay(bool enabled)
542 {
543  return this->pSocket->SetOptionNoDelay(enabled);
544 }
545 
546 inline SocketError TlsSocket::GetOptionNoDelay(bool& enabled)
547 {
548  return this->pSocket->GetOptionNoDelay(enabled);
549 }
550 
551 inline SocketError TlsSocket::SetOptionLinger(bool enable, size_t timeout)
552 {
553  return this->pSocket->SetOptionLinger(enable, timeout);
554 }
555 
556 inline SocketError TlsSocket::GetOptionLinger(bool& enable, size_t& timeout)
557 {
558  return this->pSocket->GetOptionLinger(enable, timeout);
559 }
560 
561 inline SocketError TlsSocket::SetOptionBlocking(bool enable)
562 {
563  return this->pSocket->SetOptionBlocking(enable);
564 }
565 
566 }}}} // 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
Definition: ItemInfo.hpp:8
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