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