1//
2// SecureStreamSocket.h
3//
4// Library: NetSSL_OpenSSL
5// Package: SSLSockets
6// Module: SecureStreamSocket
7//
8// Definition of the SecureStreamSocket 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
16
17#ifndef NetSSL_SecureStreamSocket_INCLUDED
18#define NetSSL_SecureStreamSocket_INCLUDED
19
20
21#include "Poco/Net/NetSSL.h"
22#include "Poco/Net/StreamSocket.h"
23#include "Poco/Net/Context.h"
24#include "Poco/Net/Session.h"
25#include "Poco/Net/X509Certificate.h"
26
27
28namespace Poco {
29namespace Net {
30
31
32class NetSSL_API SecureStreamSocket: public StreamSocket
33 /// A subclass of StreamSocket for secure SSL sockets.
34 ///
35 /// A few notes about nonblocking IO:
36 /// sendBytes() and receiveBytes() can return a
37 /// negative value when using a nonblocking socket, which means
38 /// a SSL handshake is currently in progress and more data
39 /// needs to be read or written for the handshake to continue.
40 /// If sendBytes() or receiveBytes() return ERR_SSL_WANT_WRITE,
41 /// sendBytes() must be called as soon as possible (usually, after
42 /// select() indicates that data can be written). Likewise, if
43 /// ERR_SSL_WANT_READ is returned, receiveBytes() must be called
44 /// as soon as data is available for reading (indicated by select()).
45 ///
46 /// The SSL handshake is delayed until the first sendBytes() or
47 /// receiveBytes() operation is performed on the socket. No automatic
48 /// post connection check (checking the peer certificate for a valid
49 /// hostname) is performed when using nonblocking I/O. To manually
50 /// perform peer certificate validation, call verifyPeerCertificate()
51 /// after the SSL handshake has been completed.
52{
53public:
54 enum
55 {
56 ERR_SSL_WANT_READ = -1,
57 ERR_SSL_WANT_WRITE = -2
58 };
59
60 SecureStreamSocket();
61 /// Creates an unconnected secure stream socket
62 /// using the default client SSL context.
63 ///
64 /// Before sending or receiving data, the socket
65 /// must be connected with a call to connect().
66
67 explicit SecureStreamSocket(Context::Ptr pContext);
68 /// Creates an unconnected secure stream socket
69 /// using the given SSL context.
70 ///
71 /// Before sending or receiving data, the socket
72 /// must be connected with a call to connect().
73
74 SecureStreamSocket(Context::Ptr pContext, Session::Ptr pSession);
75 /// Creates an unconnected secure stream socket
76 /// using the given SSL context.
77 ///
78 /// Before sending or receiving data, the socket
79 /// must be connected with a call to connect().
80 ///
81 /// The given Session is reused, if possible (client session
82 /// caching is enabled for the given Context, and the server
83 /// agrees to reuse the session).
84
85 explicit SecureStreamSocket(const SocketAddress& address);
86 /// Creates a secure stream socket using the default
87 /// client SSL context and connects it to
88 /// the socket specified by address.
89
90 SecureStreamSocket(const SocketAddress& address, Context::Ptr pContext);
91 /// Creates a secure stream socket using the given
92 /// client SSL context and connects it to
93 /// the socket specified by address.
94
95 SecureStreamSocket(const SocketAddress& address, Context::Ptr pContext, Session::Ptr pSession);
96 /// Creates a secure stream socket using the given
97 /// client SSL context and connects it to
98 /// the socket specified by address.
99 ///
100 /// The given Session is reused, if possible (client session
101 /// caching is enabled for the given Context, and the server
102 /// agrees to reuse the session).
103
104 SecureStreamSocket(const SocketAddress& address, const std::string& hostName);
105 /// Creates a secure stream socket using the default
106 /// client SSL context and connects it to
107 /// the socket specified by address.
108 ///
109 /// The given host name is used for certificate verification.
110
111 SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext);
112 /// Creates a secure stream socket using the given
113 /// client SSL context and connects it to
114 /// the socket specified by address.
115 ///
116 /// The given host name is used for certificate verification.
117
118 SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext, Session::Ptr pSession);
119 /// Creates a secure stream socket using the given
120 /// client SSL context and connects it to
121 /// the socket specified by address.
122 ///
123 /// The given host name is used for certificate verification.
124 ///
125 /// The given Session is reused, if possible (client session
126 /// caching is enabled for the given Context, and the server
127 /// agrees to reuse the session).
128
129 SecureStreamSocket(const Socket& socket);
130 /// Creates the SecureStreamSocket with the SocketImpl
131 /// from another socket. The SocketImpl must be
132 /// a SecureStreamSocketImpl, otherwise an InvalidArgumentException
133 /// will be thrown.
134
135 virtual ~SecureStreamSocket();
136 /// Destroys the StreamSocket.
137
138 SecureStreamSocket& operator = (const Socket& socket);
139 /// Assignment operator.
140 ///
141 /// Releases the socket's SocketImpl and
142 /// attaches the SocketImpl from the other socket and
143 /// increments the reference count of the SocketImpl.
144
145 bool havePeerCertificate() const;
146 /// Returns true iff the peer has presented a
147 /// certificate.
148
149 X509Certificate peerCertificate() const;
150 /// Returns the peer's X509 certificate.
151 ///
152 /// Throws a SSLException if the peer did not
153 /// present a certificate.
154
155 void setPeerHostName(const std::string& hostName);
156 /// Sets the peer's host name used for certificate validation.
157
158 const std::string& getPeerHostName() const;
159 /// Returns the peer's host name used for certificate validation.
160
161 static SecureStreamSocket attach(const StreamSocket& streamSocket);
162 /// Creates a SecureStreamSocket over an existing socket
163 /// connection. The given StreamSocket must be connected.
164 /// A SSL handshake will be performed.
165
166 static SecureStreamSocket attach(const StreamSocket& streamSocket, Context::Ptr pContext);
167 /// Creates a SecureStreamSocket over an existing socket
168 /// connection. The given StreamSocket must be connected.
169 /// A SSL handshake will be performed.
170
171 static SecureStreamSocket attach(const StreamSocket& streamSocket, Context::Ptr pContext, Session::Ptr pSession);
172 /// Creates a SecureStreamSocket over an existing socket
173 /// connection. The given StreamSocket must be connected.
174 /// A SSL handshake will be performed.
175 ///
176 /// The given Session is reused, if possible (client session
177 /// caching is enabled for the given Context, and the server
178 /// agrees to reuse the session).
179
180 static SecureStreamSocket attach(const StreamSocket& streamSocket, const std::string& peerHostName);
181 /// Creates a SecureStreamSocket over an existing socket
182 /// connection. The given StreamSocket must be connected.
183 /// A SSL handshake will be performed.
184
185 static SecureStreamSocket attach(const StreamSocket& streamSocket, const std::string& peerHostName, Context::Ptr pContext);
186 /// Creates a SecureStreamSocket over an existing socket
187 /// connection. The given StreamSocket must be connected.
188 /// A SSL handshake will be performed.
189
190 static SecureStreamSocket attach(const StreamSocket& streamSocket, const std::string& peerHostName, Context::Ptr pContext, Session::Ptr pSession);
191 /// Creates a SecureStreamSocket over an existing socket
192 /// connection. The given StreamSocket must be connected.
193 /// A SSL handshake will be performed.
194 ///
195 /// The given Session is reused, if possible (client session
196 /// caching is enabled for the given Context, and the server
197 /// agrees to reuse the session).
198
199 Context::Ptr context() const;
200 /// Returns the SSL context used by this socket.
201
202 void setLazyHandshake(bool flag = true);
203 /// Enable lazy SSL handshake. If enabled, the SSL handshake
204 /// will be performed the first time date is sent or
205 /// received over the connection.
206
207 bool getLazyHandshake() const;
208 /// Returns true if setLazyHandshake(true) has been called.
209
210 void verifyPeerCertificate();
211 /// Performs post-connect (or post-accept) peer certificate validation,
212 /// using the peer host name set with setPeerHostName(), or the peer's
213 /// IP address string if no peer host name has been set.
214 ///
215 /// Should only be used for non-blocking connections, after the
216 /// initial SSL handshake has been performed (see completeHandshake()).
217
218 void verifyPeerCertificate(const std::string& hostName);
219 /// Performs post-connect (or post-accept) peer certificate validation
220 /// using the given host name.
221 ///
222 /// Should only be used for non-blocking connections, after the
223 /// initial SSL handshake has been performed (see completeHandshake()).
224
225 int completeHandshake();
226 /// Completes the SSL handshake.
227 ///
228 /// If the SSL connection was the result of an accept(),
229 /// the server-side handshake is completed, otherwise
230 /// a client-side handshake is performed.
231 ///
232 /// Returns 1 if the handshake was successful, ERR_SSL_WANT_READ or
233 /// ERR_SSL_WANT_WRITE if more data is required to complete the
234 /// handshake. In this case, completeHandshake() should be called
235 /// again, after the necessary condition has been met.
236
237 Session::Ptr currentSession();
238 /// Returns the SSL session of the current connection,
239 /// for reuse in a future connection (if session caching
240 /// is enabled).
241 ///
242 /// If no connection is established, returns null.
243
244 void useSession(Session::Ptr pSession);
245 /// Sets the SSL session to use for the next
246 /// connection. Setting a previously saved Session
247 /// object is necessary to enable session caching.
248 ///
249 /// To remove the currently set session, a null pointer
250 /// can be given.
251 ///
252 /// Must be called before connect() to be effective.
253
254 bool sessionWasReused();
255 /// Returns true iff a reused session was negotiated during
256 /// the handshake.
257
258 void abort();
259 /// Aborts the SSL connection by closing the underlying
260 /// TCP connection. No orderly SSL shutdown is performed.
261
262protected:
263 SecureStreamSocket(SocketImpl* pImpl);
264
265 friend class SecureServerSocket;
266};
267
268
269} } // namespace Poco::Net
270
271
272#endif // NetSSL_SecureStreamSocket_INCLUDED
273