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