1//
2// Context.h
3//
4// Library: NetSSL_OpenSSL
5// Package: SSLCore
6// Module: Context
7//
8// Definition of the Context 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_Context_INCLUDED
18#define NetSSL_Context_INCLUDED
19
20
21#include "Poco/Net/NetSSL.h"
22#include "Poco/Net/SocketDefs.h"
23#include "Poco/Crypto/X509Certificate.h"
24#include "Poco/Crypto/RSAKey.h"
25#include "Poco/RefCountedObject.h"
26#include "Poco/AutoPtr.h"
27#include <openssl/ssl.h>
28#include <cstdlib>
29
30
31namespace Poco {
32namespace Net {
33
34
35class NetSSL_API Context: public Poco::RefCountedObject
36 /// This class encapsulates context information for
37 /// an SSL server or client, such as the certificate
38 /// verification mode and the location of certificates
39 /// and private key files, as well as the list of
40 /// supported ciphers.
41 ///
42 /// The Context class is also used to control
43 /// SSL session caching on the server and client side.
44{
45public:
46 typedef Poco::AutoPtr<Context> Ptr;
47
48 enum Usage
49 {
50 CLIENT_USE, /// Context is used by a client.
51 SERVER_USE, /// Context is used by a server.
52 TLSV1_CLIENT_USE, /// Context is used by a client requiring TLSv1.
53 TLSV1_SERVER_USE, /// Context is used by a server requiring TLSv1.
54 TLSV1_1_CLIENT_USE, /// Context is used by a client requiring TLSv1.1 (OpenSSL 1.0.0 or newer).
55 TLSV1_1_SERVER_USE, /// Context is used by a server requiring TLSv1.1 (OpenSSL 1.0.0 or newer).
56 TLSV1_2_CLIENT_USE, /// Context is used by a client requiring TLSv1.2 (OpenSSL 1.0.1 or newer).
57 TLSV1_2_SERVER_USE /// Context is used by a server requiring TLSv1.2 (OpenSSL 1.0.1 or newer).
58 };
59
60 enum VerificationMode
61 {
62 VERIFY_NONE = SSL_VERIFY_NONE,
63 /// Server: The server will not send a client certificate
64 /// request to the client, so the client will not send a certificate.
65 ///
66 /// Client: If not using an anonymous cipher (by default disabled),
67 /// the server will send a certificate which will be checked, but
68 /// the result of the check will be ignored.
69
70 VERIFY_RELAXED = SSL_VERIFY_PEER,
71 /// Server: The server sends a client certificate request to the
72 /// client. The certificate returned (if any) is checked.
73 /// If the verification process fails, the TLS/SSL handshake is
74 /// immediately terminated with an alert message containing the
75 /// reason for the verification failure.
76 ///
77 /// Client: The server certificate is verified, if one is provided.
78 /// If the verification process fails, the TLS/SSL handshake is
79 /// immediately terminated with an alert message containing the
80 /// reason for the verification failure.
81
82 VERIFY_STRICT = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
83 /// Server: If the client did not return a certificate, the TLS/SSL
84 /// handshake is immediately terminated with a handshake failure
85 /// alert.
86 ///
87 /// Client: Same as VERIFY_RELAXED.
88
89 VERIFY_ONCE = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE
90 /// Server: Only request a client certificate on the initial
91 /// TLS/SSL handshake. Do not ask for a client certificate
92 /// again in case of a renegotiation.
93 ///
94 /// Client: Same as VERIFY_RELAXED.
95 };
96
97 enum Protocols
98 {
99 PROTO_SSLV2 = 0x01,
100 PROTO_SSLV3 = 0x02,
101 PROTO_TLSV1 = 0x04,
102 PROTO_TLSV1_1 = 0x08,
103 PROTO_TLSV1_2 = 0x10
104 };
105
106 struct Params
107 {
108 Params();
109 /// Initializes the struct with default values.
110
111 std::string privateKeyFile;
112 /// Path to the private key file used for encryption.
113 /// Can be empty if no private key file is used.
114
115 std::string certificateFile;
116 /// Path to the certificate file (in PEM format).
117 /// If the private key and the certificate are stored in the same file, this
118 /// can be empty if privateKeyFile is given.
119
120 std::string caLocation;
121 /// Path to the file or directory containing the CA/root certificates.
122 /// Can be empty if the OpenSSL builtin CA certificates
123 /// are used (see loadDefaultCAs).
124
125 VerificationMode verificationMode;
126 /// Specifies whether and how peer certificates are validated.
127 /// Defaults to VERIFY_RELAXED.
128
129 int verificationDepth;
130 /// Sets the upper limit for verification chain sizes. Verification
131 /// will fail if a certificate chain larger than this is encountered.
132 /// Defaults to 9.
133
134 bool loadDefaultCAs;
135 /// Specifies whether the builtin CA certificates from OpenSSL are used.
136 /// Defaults to false.
137
138 std::string cipherList;
139 /// Specifies the supported ciphers in OpenSSL notation.
140 /// Defaults to "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH".
141
142 std::string dhParamsFile;
143 /// Specifies a file containing Diffie-Hellman parameters.
144 /// If empty, the default parameters are used.
145
146 std::string ecdhCurve;
147 /// Specifies the name of the curve to use for ECDH, based
148 /// on the curve names specified in RFC 4492.
149 /// Defaults to "prime256v1".
150 };
151
152 Context(Usage usage, const Params& params);
153 /// Creates a Context using the given parameters.
154 ///
155 /// * usage specifies whether the context is used by a client or server.
156 /// * params specifies the context parameters.
157
158 Context(
159 Usage usage,
160 const std::string& privateKeyFile,
161 const std::string& certificateFile,
162 const std::string& caLocation,
163 VerificationMode verificationMode = VERIFY_RELAXED,
164 int verificationDepth = 9,
165 bool loadDefaultCAs = false,
166 const std::string& cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
167 /// Creates a Context.
168 ///
169 /// * usage specifies whether the context is used by a client or server.
170 /// * privateKeyFile contains the path to the private key file used for encryption.
171 /// Can be empty if no private key file is used.
172 /// * certificateFile contains the path to the certificate file (in PEM format).
173 /// If the private key and the certificate are stored in the same file, this
174 /// can be empty if privateKeyFile is given.
175 /// * caLocation contains the path to the file or directory containing the
176 /// CA/root certificates. Can be empty if the OpenSSL builtin CA certificates
177 /// are used (see loadDefaultCAs).
178 /// * verificationMode specifies whether and how peer certificates are validated.
179 /// * verificationDepth sets the upper limit for verification chain sizes. Verification
180 /// will fail if a certificate chain larger than this is encountered.
181 /// * loadDefaultCAs specifies whether the builtin CA certificates from OpenSSL are used.
182 /// * cipherList specifies the supported ciphers in OpenSSL notation.
183 ///
184 /// Note: If the private key is protected by a passphrase, a PrivateKeyPassphraseHandler
185 /// must have been setup with the SSLManager, or the SSLManager's PrivateKeyPassphraseRequired
186 /// event must be handled.
187
188 Context(
189 Usage usage,
190 const std::string& caLocation,
191 VerificationMode verificationMode = VERIFY_RELAXED,
192 int verificationDepth = 9,
193 bool loadDefaultCAs = false,
194 const std::string& cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
195 /// Creates a Context.
196 ///
197 /// * usage specifies whether the context is used by a client or server.
198 /// * caLocation contains the path to the file or directory containing the
199 /// CA/root certificates. Can be empty if the OpenSSL builtin CA certificates
200 /// are used (see loadDefaultCAs).
201 /// * verificationMode specifies whether and how peer certificates are validated.
202 /// * verificationDepth sets the upper limit for verification chain sizes. Verification
203 /// will fail if a certificate chain larger than this is encountered.
204 /// * loadDefaultCAs specifies whether the builtin CA certificates from OpenSSL are used.
205 /// * cipherList specifies the supported ciphers in OpenSSL notation.
206 ///
207 /// Note that a private key and/or certificate must be specified with
208 /// usePrivateKey()/useCertificate() before the Context can be used.
209
210 ~Context();
211 /// Destroys the Context.
212
213 void useCertificate(const Poco::Crypto::X509Certificate& certificate);
214 /// Sets the certificate to be used by the Context.
215 ///
216 /// To set-up a complete certificate chain, it might be
217 /// necessary to call addChainCertificate() to specify
218 /// additional certificates.
219 ///
220 /// Note that useCertificate() must always be called before
221 /// usePrivateKey().
222
223 void addChainCertificate(const Poco::Crypto::X509Certificate& certificate);
224 /// Adds a certificate for certificate chain validation.
225
226 void usePrivateKey(const Poco::Crypto::RSAKey& key);
227 /// Sets the private key to be used by the Context.
228 ///
229 /// Note that useCertificate() must always be called before
230 /// usePrivateKey().
231 ///
232 /// Note: If the private key is protected by a passphrase, a PrivateKeyPassphraseHandler
233 /// must have been setup with the SSLManager, or the SSLManager's PrivateKeyPassphraseRequired
234 /// event must be handled.
235
236 SSL_CTX* sslContext() const;
237 /// Returns the underlying OpenSSL SSL Context object.
238
239 Usage usage() const;
240 /// Returns whether the context is for use by a client or by a server
241 /// and whether TLSv1 is required.
242
243 bool isForServerUse() const;
244 /// Returns true iff the context is for use by a server.
245
246 Context::VerificationMode verificationMode() const;
247 /// Returns the verification mode.
248
249 void enableSessionCache(bool flag = true);
250 /// Enable or disable SSL/TLS session caching.
251 /// For session caching to work, it must be enabled
252 /// on the server, as well as on the client side.
253 ///
254 /// The default is disabled session caching.
255 ///
256 /// To enable session caching on the server side, use the
257 /// two-argument version of this method to specify
258 /// a session ID context.
259
260 void enableSessionCache(bool flag, const std::string& sessionIdContext);
261 /// Enables or disables SSL/TLS session caching on the server.
262 /// For session caching to work, it must be enabled
263 /// on the server, as well as on the client side.
264 ///
265 /// SessionIdContext contains the application's unique
266 /// session ID context, which becomes part of each
267 /// session identifier generated by the server within this
268 /// context. SessionIdContext can be an arbitrary sequence
269 /// of bytes with a maximum length of SSL_MAX_SSL_SESSION_ID_LENGTH.
270 ///
271 /// A non-empty sessionIdContext should be specified even if
272 /// session caching is disabled to avoid problems with clients
273 /// requesting to reuse a session (e.g. Firefox 3.6).
274 ///
275 /// This method may only be called on SERVER_USE Context objects.
276
277 bool sessionCacheEnabled() const;
278 /// Returns true iff the session cache is enabled.
279
280 void setSessionCacheSize(std::size_t size);
281 /// Sets the maximum size of the server session cache, in number of
282 /// sessions. The default size (according to OpenSSL documentation)
283 /// is 1024*20, which may be too large for many applications,
284 /// especially on embedded platforms with limited memory.
285 ///
286 /// Specifying a size of 0 will set an unlimited cache size.
287 ///
288 /// This method may only be called on SERVER_USE Context objects.
289
290 std::size_t getSessionCacheSize() const;
291 /// Returns the current maximum size of the server session cache.
292 ///
293 /// This method may only be called on SERVER_USE Context objects.
294
295 void setSessionTimeout(long seconds);
296 /// Sets the timeout (in seconds) of cached sessions on the server.
297 /// A cached session will be removed from the cache if it has
298 /// not been used for the given number of seconds.
299 ///
300 /// This method may only be called on SERVER_USE Context objects.
301
302 long getSessionTimeout() const;
303 /// Returns the timeout (in seconds) of cached sessions on the server.
304 ///
305 /// This method may only be called on SERVER_USE Context objects.
306
307 void flushSessionCache();
308 /// Flushes the SSL session cache on the server.
309 ///
310 /// This method may only be called on SERVER_USE Context objects.
311
312 void enableExtendedCertificateVerification(bool flag = true);
313 /// Enable or disable the automatic post-connection
314 /// extended certificate verification.
315 ///
316 /// See X509Certificate::verify() for more information.
317
318 bool extendedCertificateVerificationEnabled() const;
319 /// Returns true iff automatic extended certificate
320 /// verification is enabled.
321
322 void disableStatelessSessionResumption();
323 /// Newer versions of OpenSSL support RFC 4507 tickets for stateless
324 /// session resumption.
325 ///
326 /// The feature can be disabled by calling this method.
327
328 void disableProtocols(int protocols);
329 /// Disables the given protocols.
330 ///
331 /// The protocols to be disabled are specified by OR-ing
332 /// values from the Protocols enumeration, e.g.:
333 ///
334 /// context.disableProtocols(PROTO_SSLV2 | PROTO_SSLV3);
335
336 void preferServerCiphers();
337 /// When choosing a cipher, use the server's preferences instead of the client
338 /// preferences. When not called, the SSL server will always follow the clients
339 /// preferences. When called, the SSL/TLS server will choose following its own
340 /// preferences.
341
342private:
343 void init(const Params& params);
344 /// Initializes the Context with the given parameters.
345
346 void initDH(const std::string& dhFile);
347 /// Initializes the Context with Diffie-Hellman parameters.
348
349 void initECDH(const std::string& curve);
350 /// Initializes the Context with Elliptic-Curve Diffie-Hellman key
351 /// exchange curve parameters.
352
353 void createSSLContext();
354 /// Create a SSL_CTX object according to Context configuration.
355
356 Usage _usage;
357 VerificationMode _mode;
358 SSL_CTX* _pSSLContext;
359 bool _extendedCertificateVerification;
360};
361
362
363//
364// inlines
365//
366inline Context::Usage Context::usage() const
367{
368 return _usage;
369}
370
371
372inline bool Context::isForServerUse() const
373{
374 return _usage == SERVER_USE
375 || _usage == TLSV1_SERVER_USE
376 || _usage == TLSV1_1_SERVER_USE
377 || _usage == TLSV1_2_SERVER_USE;
378}
379
380
381inline Context::VerificationMode Context::verificationMode() const
382{
383 return _mode;
384}
385
386
387inline SSL_CTX* Context::sslContext() const
388{
389 return _pSSLContext;
390}
391
392
393inline bool Context::extendedCertificateVerificationEnabled() const
394{
395 return _extendedCertificateVerification;
396}
397
398
399} } // namespace Poco::Net
400
401
402#endif // NetSSL_Context_INCLUDED
403