SecureSocketImpl.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. //
  2. // SecureSocketImpl.h
  3. //
  4. // Library: NetSSL_OpenSSL
  5. // Package: SSLSockets
  6. // Module: SecureSocketImpl
  7. //
  8. // Definition of the SecureSocketImpl class.
  9. //
  10. // Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #ifndef NetSSL_SecureSocketImpl_INCLUDED
  16. #define NetSSL_SecureSocketImpl_INCLUDED
  17. #include "Poco/Net/NetSSL.h"
  18. #include "Poco/Net/SocketImpl.h"
  19. #include "Poco/Net/Context.h"
  20. #include "Poco/Net/X509Certificate.h"
  21. #include "Poco/Net/Session.h"
  22. #include <openssl/bio.h>
  23. #include <openssl/ssl.h>
  24. namespace Poco {
  25. namespace Net {
  26. class HostEntry;
  27. class NetSSL_API SecureSocketImpl
  28. /// The SocketImpl for SecureStreamSocket.
  29. {
  30. public:
  31. SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Context::Ptr pContext);
  32. /// Creates the SecureSocketImpl using an already
  33. /// connected stream socket.
  34. virtual ~SecureSocketImpl();
  35. /// Destroys the SecureSocketImpl.
  36. SocketImpl* acceptConnection(SocketAddress& clientAddr);
  37. /// Get the next completed connection from the
  38. /// socket's completed connection queue.
  39. ///
  40. /// If the queue is empty, waits until a connection
  41. /// request completes.
  42. ///
  43. /// Returns a new SSL socket for the connection
  44. /// with the client.
  45. ///
  46. /// The client socket's address is returned in clientAddr.
  47. void connect(const SocketAddress& address, bool performHandshake);
  48. /// Initializes the socket and establishes a secure connection to
  49. /// the TCP server at the given address.
  50. ///
  51. /// If performHandshake is true, the SSL handshake is performed immediately
  52. /// after establishing the connection. Otherwise, the handshake is performed
  53. /// the first time sendBytes(), receiveBytes() or completeHandshake() is called.
  54. void connect(const SocketAddress& address, const Poco::Timespan& timeout, bool performHandshake);
  55. /// Initializes the socket, sets the socket timeout and
  56. /// establishes a secure connection to the TCP server at the given address.
  57. ///
  58. /// If performHandshake is true, the SSL handshake is performed immediately
  59. /// after establishing the connection. Otherwise, the handshake is performed
  60. /// the first time sendBytes(), receiveBytes() or completeHandshake() is called.
  61. void connectNB(const SocketAddress& address);
  62. /// Initializes the socket and establishes a secure connection to
  63. /// the TCP server at the given address. Prior to opening the
  64. /// connection the socket is set to nonblocking mode.
  65. void bind(const SocketAddress& address, bool reuseAddress = false);
  66. /// Bind a local address to the socket.
  67. ///
  68. /// This is usually only done when establishing a server
  69. /// socket. SSL clients should not bind a socket to a
  70. /// specific address.
  71. ///
  72. /// If reuseAddress is true, sets the SO_REUSEADDR
  73. /// socket option.
  74. void listen(int backlog = 64);
  75. /// Puts the socket into listening state.
  76. ///
  77. /// The socket becomes a passive socket that
  78. /// can accept incoming connection requests.
  79. ///
  80. /// The backlog argument specifies the maximum
  81. /// number of connections that can be queued
  82. /// for this socket.
  83. void shutdown();
  84. /// Shuts down the connection by attempting
  85. /// an orderly SSL shutdown, then actually
  86. /// shutting down the TCP connection.
  87. void close();
  88. /// Close the socket.
  89. void abort();
  90. /// Aborts the connection by closing the
  91. /// underlying TCP connection. No orderly SSL shutdown
  92. /// is performed.
  93. int sendBytes(const void* buffer, int length, int flags = 0);
  94. /// Sends the contents of the given buffer through
  95. /// the socket. Any specified flags are ignored.
  96. ///
  97. /// Returns the number of bytes sent, which may be
  98. /// less than the number of bytes specified.
  99. int receiveBytes(void* buffer, int length, int flags = 0);
  100. /// Receives data from the socket and stores it
  101. /// in buffer. Up to length bytes are received.
  102. ///
  103. /// Returns the number of bytes received.
  104. int available() const;
  105. /// Returns the number of bytes available from the
  106. /// SSL buffer for immediate reading.
  107. int completeHandshake();
  108. /// Completes the SSL handshake.
  109. ///
  110. /// If the SSL connection was the result of an accept(),
  111. /// the server-side handshake is completed, otherwise
  112. /// a client-side handshake is performed.
  113. poco_socket_t sockfd();
  114. /// Returns the underlying socket descriptor.
  115. X509* peerCertificate() const;
  116. /// Returns the peer's certificate.
  117. Context::Ptr context() const;
  118. /// Returns the SSL context used for this socket.
  119. void verifyPeerCertificate();
  120. /// Performs post-connect (or post-accept) peer certificate validation,
  121. /// using the peer host name set with setPeerHostName(), or the peer's
  122. /// IP address string if no peer host name has been set.
  123. void verifyPeerCertificate(const std::string& hostName);
  124. /// Performs post-connect (or post-accept) peer certificate validation
  125. /// using the given peer host name.
  126. void setPeerHostName(const std::string& hostName);
  127. /// Sets the peer host name for certificate validation purposes.
  128. const std::string& getPeerHostName() const;
  129. /// Returns the peer host name.
  130. Session::Ptr currentSession();
  131. /// Returns the SSL session of the current connection,
  132. /// for reuse in a future connection (if session caching
  133. /// is enabled).
  134. ///
  135. /// If no connection is established, returns null.
  136. void useSession(Session::Ptr pSession);
  137. /// Sets the SSL session to use for the next
  138. /// connection. Setting a previously saved Session
  139. /// object is necessary to enable session caching.
  140. ///
  141. /// To remove the currently set session, a null pointer
  142. /// can be given.
  143. ///
  144. /// Must be called before connect() to be effective.
  145. bool sessionWasReused();
  146. /// Returns true iff a reused session was negotiated during
  147. /// the handshake.
  148. protected:
  149. void acceptSSL();
  150. /// Performs a server-side SSL handshake and certificate verification.
  151. void connectSSL(bool performHandshake);
  152. /// Performs a client-side SSL handshake and establishes a secure
  153. /// connection over an already existing TCP connection.
  154. long verifyPeerCertificateImpl(const std::string& hostName);
  155. /// Performs post-connect (or post-accept) peer certificate validation.
  156. static bool isLocalHost(const std::string& hostName);
  157. /// Returns true iff the given host name is the local host
  158. /// (either "localhost" or "127.0.0.1").
  159. bool mustRetry(int rc);
  160. /// Returns true if the last operation should be retried,
  161. /// otherwise false.
  162. ///
  163. /// In case of an SSL_ERROR_WANT_READ error, and if the socket is
  164. /// blocking, waits for the underlying socket to become readable.
  165. ///
  166. /// In case of an SSL_ERROR_WANT_WRITE error, and if the socket is
  167. /// blocking, waits for the underlying socket to become writable.
  168. ///
  169. /// Can also throw a Poco::TimeoutException if the socket does
  170. /// not become readable or writable within the sockets
  171. /// receive or send timeout.
  172. int handleError(int rc);
  173. /// Handles an SSL error by throwing an appropriate exception.
  174. void reset();
  175. /// Prepares the socket for re-use.
  176. ///
  177. /// After closing and resetting a socket, the socket can
  178. /// be used for a new connection.
  179. ///
  180. /// Note that simply closing a socket is not sufficient
  181. /// to be able to re-use it again.
  182. private:
  183. SecureSocketImpl(const SecureSocketImpl&);
  184. SecureSocketImpl& operator = (const SecureSocketImpl&);
  185. SSL* _pSSL;
  186. Poco::AutoPtr<SocketImpl> _pSocket;
  187. Context::Ptr _pContext;
  188. bool _needHandshake;
  189. std::string _peerHostName;
  190. Session::Ptr _pSession;
  191. friend class SecureStreamSocketImpl;
  192. };
  193. //
  194. // inlines
  195. //
  196. inline poco_socket_t SecureSocketImpl::sockfd()
  197. {
  198. return _pSocket->sockfd();
  199. }
  200. inline Context::Ptr SecureSocketImpl::context() const
  201. {
  202. return _pContext;
  203. }
  204. inline const std::string& SecureSocketImpl::getPeerHostName() const
  205. {
  206. return _peerHostName;
  207. }
  208. } } // namespace Poco::Net
  209. #endif // NetSSL_SecureSocketImpl_INCLUDED