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
32 namespace Poco {
33 namespace Net {
34
35
36 class 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 /// Make sure that the TLSv1.3 cipher suites are enabled:
50 ///
51 /// - TLS_AES_256_GCM_SHA384
52 /// - TLS_CHACHA20_POLY1305_SHA256
53 /// - TLS_AES_128_GCM_SHA256
54 /// - TLS_AES_128_CCM_8_SHA256
55 /// - TLS_AES_128_CCM_SHA256
56 ///
57 /// The first three of the above cipher suites should be enabled
58 /// by default in OpenSSL if you do not provide an explicit
59 /// cipher configuration (cipherList).
60 {
61 public:
62 using Ptr = Poco::AutoPtr<Context>;
63
64 enum Usage
65 {
66 TLS_CLIENT_USE, /// Context is used by a client for TLSv1 or higher. Use requireMinimumProtocol() or disableProtocols() to disable undesired older versions.
67 TLS_SERVER_USE, /// Context is used by a client for TLSv1 or higher. Use requireMinimumProtocol() or disableProtocols() to disable undesired older versions.
68 CLIENT_USE, /// DEPRECATED. Context is used by a client.
69 SERVER_USE, /// DEPRECATED. Context is used by a server.
70 TLSV1_CLIENT_USE, /// DEPRECATED. Context is used by a client requiring TLSv1.
71 TLSV1_SERVER_USE, /// DEPRECATED. Context is used by a server requiring TLSv1.
72 TLSV1_1_CLIENT_USE, /// DEPRECATED. Context is used by a client requiring TLSv1.1 (OpenSSL 1.0.0 or newer).
73 TLSV1_1_SERVER_USE, /// DEPRECATED. Context is used by a server requiring TLSv1.1 (OpenSSL 1.0.0 or newer).
74 TLSV1_2_CLIENT_USE, /// DEPRECATED. Context is used by a client requiring TLSv1.2 (OpenSSL 1.0.1 or newer).
75 TLSV1_2_SERVER_USE, /// DEPRECATED. Context is used by a server requiring TLSv1.2 (OpenSSL 1.0.1 or newer).
76 TLSV1_3_CLIENT_USE, /// DEPRECATED. Context is used by a client requiring TLSv1.3 (OpenSSL 1.1.1 or newer).
77 TLSV1_3_SERVER_USE /// DEPRECATED. 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 bool dhUse2048Bits;
168 /// If set to true, will use 2048-bit MODP Group with 256-bit
169 /// prime order subgroup (RFC5114) instead of 1024-bit for DH.
170
171 std::string ecdhCurve;
172 /// OpenSSL 1.0.1 and earlier:
173 /// Specifies the name of the curve to use for ECDH, based
174 /// on the curve names specified in RFC 4492.
175 /// Defaults to "prime256v1".
176 /// OpenSSL 1.0.2 to 1.1.0:
177 /// Specifies the colon-separated list of curves
178 /// to be used for ECDH, based on the curve names
179 /// defined by OpenSSL, such as
180 /// "X448:X25519:P-521:P-384:P-256"
181 /// Defaults to the subset supported by the OpenSSL version
182 /// among the above.
183 /// OpenSSL 1.1.1 and above:
184 /// Specifies the colon-separated list of groups
185 /// (some of which can be curves) to be used for ECDH
186 /// and other TLSv1.3 ephemeral key negotiation, based
187 /// on the group names defined by OpenSSL. Defaults to
188 /// "X448:X25519:ffdhe4096:ffdhe3072:ffdhe2048:ffdhe6144:ffdhe8192:P-521:P-384:P-256"
189 };
190
191 Context(Usage usage, const Params& params);
192 /// Creates a Context using the given parameters.
193 ///
194 /// * usage specifies whether the context is used by a client or server.
195 /// * params specifies the context parameters.
196
197 Context(
198 Usage usage,
199 const std::string& privateKeyFile,
200 const std::string& certificateFile,
201 const std::string& caLocation,
202 VerificationMode verificationMode = VERIFY_RELAXED,
203 int verificationDepth = 9,
204 bool loadDefaultCAs = false,
205 const std::string& cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
206 /// Creates a Context.
207 ///
208 /// * usage specifies whether the context is used by a client or server.
209 /// * privateKeyFile contains the path to the private key file used for encryption.
210 /// Can be empty if no private key file is used.
211 /// * certificateFile contains the path to the certificate file (in PEM format).
212 /// If the private key and the certificate are stored in the same file, this
213 /// can be empty if privateKeyFile is given.
214 /// * caLocation contains the path to the file or directory containing the
215 /// CA/root certificates. Can be empty if the OpenSSL builtin CA certificates
216 /// are used (see loadDefaultCAs).
217 /// * verificationMode specifies whether and how peer certificates are validated.
218 /// * verificationDepth sets the upper limit for verification chain sizes. Verification
219 /// will fail if a certificate chain larger than this is encountered.
220 /// * loadDefaultCAs specifies whether the builtin CA certificates from OpenSSL are used.
221 /// * cipherList specifies the supported ciphers in OpenSSL notation.
222 ///
223 /// Note: If the private key is protected by a passphrase, a PrivateKeyPassphraseHandler
224 /// must have been setup with the SSLManager, or the SSLManager's PrivateKeyPassphraseRequired
225 /// event must be handled.
226
227 Context(
228 Usage usage,
229 const std::string& caLocation,
230 VerificationMode verificationMode = VERIFY_RELAXED,
231 int verificationDepth = 9,
232 bool loadDefaultCAs = false,
233 const std::string& cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
234 /// Creates a Context.
235 ///
236 /// * usage specifies whether the context is used by a client or server.
237 /// * caLocation contains the path to the file or directory containing the
238 /// CA/root certificates. Can be empty if the OpenSSL builtin CA certificates
239 /// are used (see loadDefaultCAs).
240 /// * verificationMode specifies whether and how peer certificates are validated.
241 /// * verificationDepth sets the upper limit for verification chain sizes. Verification
242 /// will fail if a certificate chain larger than this is encountered.
243 /// * loadDefaultCAs specifies whether the builtin CA certificates from OpenSSL are used.
244 /// * cipherList specifies the supported ciphers in OpenSSL notation.
245 ///
246 /// Note that a private key and/or certificate must be specified with
247 /// usePrivateKey()/useCertificate() before the Context can be used.
248
249 ~Context();
250 /// Destroys the Context.
251
252 void useCertificate(const Poco::Crypto::X509Certificate& certificate);
253 /// Sets the certificate to be used by the Context.
254 ///
255 /// To set-up a complete certificate chain, it might be
256 /// necessary to call addChainCertificate() to specify
257 /// additional certificates.
258 ///
259 /// Note that useCertificate() must always be called before
260 /// usePrivateKey().
261
262 void addChainCertificate(const Poco::Crypto::X509Certificate& certificate);
263 /// Adds a certificate for certificate chain validation.
264
265 void addCertificateAuthority(const Poco::Crypto::X509Certificate& certificate);
266 /// Add one trusted certification authority to be used by the Context.
267
268 void usePrivateKey(const Poco::Crypto::RSAKey& key);
269 /// Sets the private key to be used by the Context.
270 ///
271 /// Note that useCertificate() must always be called before
272 /// usePrivateKey().
273 ///
274 /// Note: If the private key is protected by a passphrase, a PrivateKeyPassphraseHandler
275 /// must have been setup with the SSLManager, or the SSLManager's PrivateKeyPassphraseRequired
276 /// event must be handled.
277
278 void usePrivateKey(const Poco::Crypto::EVPPKey &pkey);
279 /// Sets the private key to be used by the Context.
280 ///
281 /// Note that useCertificate() must always be called before
282 /// usePrivateKey().
283 ///
284 /// Note: If the private key is protected by a passphrase, a PrivateKeyPassphraseHandler
285 /// must have been setup with the SSLManager, or the SSLManager's PrivateKeyPassphraseRequired
286 /// event must be handled.
287
288 SSL_CTX* sslContext() const;
289 /// Returns the underlying OpenSSL SSL Context object.
290
291 Usage usage() const;
292 /// Returns whether the context is for use by a client or by a server
293 /// and whether TLSv1 is required.
294
295 bool isForServerUse() const;
296 /// Returns true iff the context is for use by a server.
297
298 Context::VerificationMode verificationMode() const;
299 /// Returns the verification mode.
300
301 void enableSessionCache(bool flag = true);
302 /// Enable or disable SSL/TLS session caching.
303 /// For session caching to work, it must be enabled
304 /// on the server, as well as on the client side.
305 ///
306 /// The default is disabled session caching.
307 ///
308 /// To enable session caching on the server side, use the
309 /// two-argument version of this method to specify
310 /// a session ID context.
311
312 void enableSessionCache(bool flag, const std::string& sessionIdContext);
313 /// Enables or disables SSL/TLS session caching on the server.
314 /// For session caching to work, it must be enabled
315 /// on the server, as well as on the client side.
316 ///
317 /// SessionIdContext contains the application's unique
318 /// session ID context, which becomes part of each
319 /// session identifier generated by the server within this
320 /// context. SessionIdContext can be an arbitrary sequence
321 /// of bytes with a maximum length of SSL_MAX_SSL_SESSION_ID_LENGTH.
322 ///
323 /// A non-empty sessionIdContext should be specified even if
324 /// session caching is disabled to avoid problems with clients
325 /// requesting to reuse a session (e.g. Firefox 3.6).
326 ///
327 /// This method may only be called on SERVER_USE Context objects.
328
329 bool sessionCacheEnabled() const;
330 /// Returns true iff the session cache is enabled.
331
332 void setSessionCacheSize(std::size_t size);
333 /// Sets the maximum size of the server session cache, in number of
334 /// sessions. The default size (according to OpenSSL documentation)
335 /// is 1024*20, which may be too large for many applications,
336 /// especially on embedded platforms with limited memory.
337 ///
338 /// Specifying a size of 0 will set an unlimited cache size.
339 ///
340 /// This method may only be called on SERVER_USE Context objects.
341
342 std::size_t getSessionCacheSize() const;
343 /// Returns the current maximum size of the server session cache.
344 ///
345 /// This method may only be called on SERVER_USE Context objects.
346
347 void setSessionTimeout(long seconds);
348 /// Sets the timeout (in seconds) of cached sessions on the server.
349 /// A cached session will be removed from the cache if it has
350 /// not been used for the given number of seconds.
351 ///
352 /// This method may only be called on SERVER_USE Context objects.
353
354 long getSessionTimeout() const;
355 /// Returns the timeout (in seconds) of cached sessions on the server.
356 ///
357 /// This method may only be called on SERVER_USE Context objects.
358
359 void flushSessionCache();
360 /// Flushes the SSL session cache on the server.
361 ///
362 /// This method may only be called on SERVER_USE Context objects.
363
364 void enableExtendedCertificateVerification(bool flag = true);
365 /// Enable or disable the automatic post-connection
366 /// extended certificate verification.
367 ///
368 /// See X509Certificate::verify() for more information.
369
370 bool extendedCertificateVerificationEnabled() const;
371 /// Returns true iff automatic extended certificate
372 /// verification is enabled.
373
374 void disableStatelessSessionResumption();
375 /// Newer versions of OpenSSL support RFC 4507 tickets for stateless
376 /// session resumption.
377 ///
378 /// The feature can be disabled by calling this method.
379
380 void disableProtocols(int protocols);
381 /// Disables the given protocols.
382 ///
383 /// The protocols to be disabled are specified by OR-ing
384 /// values from the Protocols enumeration, e.g.:
385 ///
386 /// context.disableProtocols(PROTO_SSLV2 | PROTO_SSLV3);
387
388 void requireMinimumProtocol(Protocols protocol);
389 /// Disables all protocol version lower than the given one.
390 /// To require at least TLS 1.2 or later:
391 ///
392 /// context.requireMinimumProtocol(PROTO_TLSV1_2);
393
394 void preferServerCiphers();
395 /// When choosing a cipher, use the server's preferences instead of the client
396 /// preferences. When not called, the SSL server will always follow the clients
397 /// preferences. When called, the SSL/TLS server will choose following its own
398 /// preferences.
399
400 private:
401 void init(const Params& params);
402 /// Initializes the Context with the given parameters.
403
404 void initDH(bool use2048Bits, const std::string& dhFile);
405 /// Initializes the Context with Diffie-Hellman parameters.
406
407 void initECDH(const std::string& curve);
408 /// Initializes the Context with Elliptic-Curve Diffie-Hellman key
409 /// exchange curve parameters.
410
411 void createSSLContext();
412 /// Create a SSL_CTX object according to Context configuration.
413
414 Usage _usage;
415 VerificationMode _mode;
416 SSL_CTX* _pSSLContext;
417 bool _extendedCertificateVerification;
418 };
419
420
421 //
422 // inlines
423 //
usage()424 inline Context::Usage Context::usage() const
425 {
426 return _usage;
427 }
428
429
isForServerUse()430 inline bool Context::isForServerUse() const
431 {
432 return _usage == SERVER_USE
433 || _usage == TLS_SERVER_USE
434 || _usage == TLSV1_SERVER_USE
435 || _usage == TLSV1_1_SERVER_USE
436 || _usage == TLSV1_2_SERVER_USE
437 || _usage == TLSV1_3_SERVER_USE;
438 }
439
440
verificationMode()441 inline Context::VerificationMode Context::verificationMode() const
442 {
443 return _mode;
444 }
445
446
sslContext()447 inline SSL_CTX* Context::sslContext() const
448 {
449 return _pSSLContext;
450 }
451
452
extendedCertificateVerificationEnabled()453 inline bool Context::extendedCertificateVerificationEnabled() const
454 {
455 return _extendedCertificateVerification;
456 }
457
458
459 } } // namespace Poco::Net
460
461
462 #endif // NetSSL_Context_INCLUDED
463