PLCnext API Documentation  21.9.0.40
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 
216  SocketError Close(void);
217 
225  int Send(const void* pBuffer, size_t length, SocketError& error);
226 
234  int Receive(void* pBuffer, size_t length, SocketError& error);
235 
244  bool Select(SelectMode mode, Microseconds timeout, SocketError& error);
245 
253  SocketError SetSocketOption(SocketOptionName optionName, const void* optionValue, size_t optionLength);
254 
263  SocketError GetSocketOption(SocketOptionName optionName, void* optionValue, size_t *optionLength);
264 
275  SocketError SetOptionReuseAddress(bool enabled);
276 
284  SocketError GetOptionReuseAddress(bool& enabled);
285 
296  SocketError SetOptionKeepAlive(bool enabled);
297 
305  SocketError GetOptionKeepAlive(bool& enabled);
306 
315  SocketError SetOptionBroadcast(bool enabled);
316 
324  SocketError GetOptionBroadcast(bool& enabled);
325 
335  SocketError SetOptionNoDelay(bool enabled);
336 
344  SocketError GetOptionNoDelay(bool& enabled);
345 
361  SocketError SetOptionLinger(bool enable, size_t timeout);
362 
369  SocketError GetOptionLinger(bool& enable, size_t& timeout);
370 
374  SocketError SetOptionBlocking(bool enable);
375 
393  SocketError InitClient(const String& trustStoreName, const String& identityStoreName, const String& hostName);
394 
406  SocketError InitServer(const String& identityStoreName, const String& trustStoreName = "");
407 
416  void SetCipherList(String cipherList);
417 
418 protected: // operations
419 
420 private: // static methods
421 
422 private: // methods
423  Ptr TcpAccept(IpAddress& ip4address, int& port, SocketError& error);
424  SocketError TlsAccept(void);
425  SocketError TcpConnect(const IpAddress& ipAddress, int port);
426  SocketError TlsConnect(void);
427  SocketError HandleSslResult(int result, int* sslErrorOut = nullptr);
428  int GetFileDescriptor(void);
429  void ClearOpenSslErrors(void);
430 
431 private: // fields
432  Socket::Ptr pSocket = nullptr;
433  SSL* sslConnection = nullptr;
434  TlsContext::Ptr pContext;
435 
436  Ptr currentAcceptSocket;
437 
438  bool tlsIsConnected; //true if TLS Handshake was completed
439  bool hasSslError;
440  bool socketIsConnected; //true if tcp socket is connected / accepted (set before SSL_connect / SSL_accept)
441  bool tlsInitDone;
442  bool isInitialized; // true if InitClient resp. InitServer has already been called
443  bool tlsConnectIsPending;
444  bool pendingTlsConnectNeedsRead;
445 
446  String hostNameToVerify;
447 };
448 
450 // inline methods of class Socket
451 
452 inline SocketType TlsSocket::GetSocketType(void)
453 {
454  return this->pSocket->GetSocketType();
455 }
456 
457 inline SocketDomain TlsSocket::GetSocketDomain(void)
458 {
459  return this->pSocket->GetSocketDomain();
460 }
461 
462 inline bool TlsSocket::IsBlocking(void)
463 {
464  return this->pSocket->IsBlocking();
465 }
466 
467 inline IpAddress TlsSocket::GetRemoteIpAddress(void)
468 {
469  return this->pSocket->GetRemoteIpAddress();
470 }
471 
472 inline int TlsSocket::GetRemotePort(void)
473 {
474  return this->pSocket->GetRemotePort();
475 }
476 
477 inline bool TlsSocket::IsConnected(void)
478 {
479  return (!this->hasSslError) && (this->tlsIsConnected || this->socketIsConnected);
480 }
481 
482 inline bool TlsSocket::IsTlsConnected(void)
483 {
484  return (!this->hasSslError) && (this->tlsIsConnected);
485 }
486 
487 inline SocketError TlsSocket::Bind(const IpAddress& ip4Address, int port)
488 {
489  return pSocket->Bind(ip4Address, port);
490 }
491 
492 inline SocketError TlsSocket::Bind2(const IpAddress& ip4Address, int& port)
493 {
494  return pSocket->Bind2(ip4Address, port);
495 }
496 
497 
498 inline SocketError TlsSocket::Listen(size_t backlog)
499 {
500  return pSocket->Listen(backlog);
501 }
502 
503 inline SocketError TlsSocket::SetSocketOption(SocketOptionName optionName, const void * optionValue, size_t optionLength)
504 {
505  return this->pSocket->SetSocketOption(optionName, optionValue, optionLength);
506 }
507 
508 inline SocketError TlsSocket::GetSocketOption(SocketOptionName optionName, void * optionValue, size_t * optionLength)
509 {
510  return this->pSocket->GetSocketOption(optionName, optionValue, optionLength);
511 }
512 
513 inline SocketError TlsSocket::SetOptionReuseAddress(bool enabled)
514 {
515  return this->pSocket->SetOptionReuseAddress(enabled);
516 }
517 
518 inline SocketError TlsSocket::GetOptionReuseAddress(bool& enabled)
519 {
520  return this->pSocket->GetOptionReuseAddress(enabled);
521 }
522 
523 inline SocketError TlsSocket::SetOptionKeepAlive(bool enabled)
524 {
525  return this->pSocket->SetOptionKeepAlive(enabled);
526 }
527 
528 inline SocketError TlsSocket::GetOptionKeepAlive(bool& enabled)
529 {
530  return this->pSocket->GetOptionKeepAlive(enabled);
531 }
532 
533 inline SocketError TlsSocket::SetOptionBroadcast(bool enabled)
534 {
535  return this->pSocket->SetOptionBroadcast(enabled);
536 }
537 
538 inline SocketError TlsSocket::GetOptionBroadcast(bool& enabled)
539 {
540  return this->pSocket->GetOptionBroadcast(enabled);
541 }
542 
543 inline SocketError TlsSocket::SetOptionNoDelay(bool enabled)
544 {
545  return this->pSocket->SetOptionNoDelay(enabled);
546 }
547 
548 inline SocketError TlsSocket::GetOptionNoDelay(bool& enabled)
549 {
550  return this->pSocket->GetOptionNoDelay(enabled);
551 }
552 
553 inline SocketError TlsSocket::SetOptionLinger(bool enable, size_t timeout)
554 {
555  return this->pSocket->SetOptionLinger(enable, timeout);
556 }
557 
558 inline SocketError TlsSocket::GetOptionLinger(bool& enable, size_t& timeout)
559 {
560  return this->pSocket->GetOptionLinger(enable, timeout);
561 }
562 
563 inline SocketError TlsSocket::SetOptionBlocking(bool enable)
564 {
565  return this->pSocket->SetOptionBlocking(enable);
566 }
567 
568 }}}} // 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