2014-09-05 00:17:09 +02:00
//
// Context.h
//
2014-10-07 23:16:58 +02:00
// Library: NetSSL_Win
2014-09-05 00:17:09 +02:00
// Package: SSLCore
// Module: Context
//
// Definition of the Context class.
//
// Copyright (c) 2006-2014, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
# ifndef NetSSL_Context_INCLUDED
# define NetSSL_Context_INCLUDED
# include "Poco/Net/NetSSL.h"
# include "Poco/Net/X509Certificate.h"
# include "Poco/RefCountedObject.h"
# include "Poco/AutoPtr.h"
# include "Poco/Mutex.h"
# include <vector>
2018-05-04 14:17:49 +02:00
# if defined(POCO_OS_FAMILY_WINDOWS)
2014-09-05 00:17:09 +02:00
# include <windows.h>
# include <wincrypt.h>
# include <schannel.h>
2014-10-07 23:16:58 +02:00
# ifndef SECURITY_WIN32
# define SECURITY_WIN32
# endif
# include <security.h>
# include <sspi.h>
2018-05-04 14:17:49 +02:00
# endif
2014-09-05 00:17:09 +02:00
namespace Poco {
namespace Net {
class NetSSL_Win_API Context : public Poco : : RefCountedObject
/// This class encapsulates context information for
/// an SSL server or client, such as the certificate
/// verification mode and which certificates and
/// protocols to use.
///
/// The Context class is also used to control
/// SSL session caching on the server and client side.
{
public :
2020-01-10 11:41:49 +01:00
using Ptr = Poco : : AutoPtr < Context > ;
2014-09-05 00:17:09 +02:00
enum Usage
{
2020-01-10 11:41:49 +01:00
TLS_CLIENT_USE , /// Context is used by a client for TLSv1 or higher. Use requireMinimumProtocol() or disableProtocols() to disable undesired older versions.
TLS_SERVER_USE , /// Context is used by a client for TLSv1 or higher. Use requireMinimumProtocol() or disableProtocols() to disable undesired older versions.
CLIENT_USE , /// DEPRECATED. Context is used by a client.
SERVER_USE , /// DEPRECATED. Context is used by a server.
TLSV1_CLIENT_USE , /// DEPRECATED. Context is used by a client requiring TLSv1.
TLSV1_SERVER_USE , /// DEPRECATED. Context is used by a server requiring TLSv1.
TLSV1_1_CLIENT_USE , /// DEPRECATED. Context is used by a client requiring TLSv1.1. Not supported on Windows Embedded Compact.
TLSV1_1_SERVER_USE , /// DEPRECATED. Context is used by a server requiring TLSv1.1. Not supported on Windows Embedded Compact.
TLSV1_2_CLIENT_USE , /// DEPRECATED. Context is used by a client requiring TLSv1.2. Not supported on Windows Embedded Compact.
TLSV1_2_SERVER_USE , /// DEPRECATED. Context is used by a server requiring TLSv1.2. Not supported on Windows Embedded Compact.
TLSV1_3_CLIENT_USE , /// DEPRECATED. Context is used by a client requiring TLSv1.3. Not supported on Windows Embedded Compact.
TLSV1_3_SERVER_USE /// DEPRECATED. Context is used by a server requiring TLSv1.3. Not supported on Windows Embedded Compact.
2014-09-05 00:17:09 +02:00
} ;
2022-07-07 11:18:20 +02:00
enum VerificationMode
2014-09-05 00:17:09 +02:00
{
2022-07-07 11:18:20 +02:00
VERIFY_NONE = 0 ,
/// Server: The server will not send a client certificate
/// request to the client, so the client will not send a certificate.
2014-09-05 00:17:09 +02:00
///
2022-07-07 11:18:20 +02:00
/// Client: If not using an anonymous cipher (by default disabled),
2014-09-05 00:17:09 +02:00
/// the server will send a certificate which will be checked, but
/// the result of the check will be ignored.
2022-07-07 11:18:20 +02:00
VERIFY_RELAXED = 1 ,
/// Server: The server sends a client certificate request to the
/// client. The certificate returned (if any) is checked.
/// If the verification process fails, the TLS/SSL handshake is
/// immediately terminated with an alert message containing the
/// reason for the verification failure.
2014-09-05 00:17:09 +02:00
///
2022-07-07 11:18:20 +02:00
/// Client: The server certificate is verified, if one is provided.
2014-09-05 00:17:09 +02:00
/// If the verification process fails, the TLS/SSL handshake is
2022-07-07 11:18:20 +02:00
/// immediately terminated with an alert message containing the
/// reason for the verification failure.
2014-09-05 00:17:09 +02:00
VERIFY_STRICT = 2 ,
2022-07-07 11:18:20 +02:00
/// Server: If the client did not return a certificate, the TLS/SSL
2014-09-05 00:17:09 +02:00
/// handshake is immediately terminated with a handshake failure
2022-07-07 11:18:20 +02:00
/// alert.
2014-09-05 00:17:09 +02:00
///
2022-07-07 11:18:20 +02:00
/// Client: Same as VERIFY_RELAXED.
2014-09-05 00:17:09 +02:00
2014-10-09 20:54:07 +02:00
VERIFY_ONCE = 1
2022-07-07 11:18:20 +02:00
/// Same as VERIFY_RELAXED (provided for interface compatibility with
2014-10-09 20:54:07 +02:00
/// the OpenSSL implementation.
2014-09-05 00:17:09 +02:00
} ;
2020-01-10 11:41:49 +01:00
enum Protocols
{
PROTO_SSLV2 = 0x01 ,
PROTO_SSLV3 = 0x02 ,
PROTO_TLSV1 = 0x04 ,
PROTO_TLSV1_1 = 0x08 ,
PROTO_TLSV1_2 = 0x10 ,
PROTO_TLSV1_3 = 0x20
} ;
2014-09-05 00:17:09 +02:00
enum Options
{
OPT_PERFORM_REVOCATION_CHECK = 0x01 ,
/// Check certificates against revocation list. Not supported (ignored) on Windows Embedded Compact.
OPT_TRUST_ROOTS_WIN_CERT_STORE = 0x02 ,
/// Trust root certificates from Windows root certificate store.
OPT_USE_MACHINE_STORE = 0x04 ,
/// If specified, the windows machine certificate store is used (server only).
/// Otherwise, the user's certificate store is used.
OPT_USE_STRONG_CRYPTO = 0x08 ,
2022-07-07 11:18:20 +02:00
/// Disable known weak cryptographic algorithms, cipher suites, and
/// SSL/TLS protocol versions that may be otherwise enabled for better interoperability.
2014-10-07 23:16:58 +02:00
OPT_LOAD_CERT_FROM_FILE = 0x10 ,
2022-07-07 11:18:20 +02:00
/// Load certificate and private key from a PKCS #12 (.pfx) file,
2014-10-07 23:16:58 +02:00
/// and not from the certificate store.
2014-09-05 00:17:09 +02:00
OPT_DEFAULTS = OPT_PERFORM_REVOCATION_CHECK | OPT_TRUST_ROOTS_WIN_CERT_STORE | OPT_USE_STRONG_CRYPTO
} ;
Context ( Usage usage ,
2022-07-07 11:18:20 +02:00
const std : : string & certificateNameOrPath ,
2014-09-05 00:17:09 +02:00
VerificationMode verMode = VERIFY_RELAXED ,
int options = OPT_DEFAULTS ,
const std : : string & certificateStoreName = CERT_STORE_MY ) ;
/// Creates a Context.
2022-07-07 11:18:20 +02:00
///
2014-09-05 00:17:09 +02:00
/// * usage specifies whether the context is used by a client or server,
/// as well as which protocol to use.
2014-10-07 23:16:58 +02:00
/// * certificateNameOrPath specifies either the subject name of the certificate to use,
/// or the path of a PKCS #12 file containing the certificate and corresponding private key.
2022-07-07 11:18:20 +02:00
/// If a subject name is specified, the certificate must be located in the certificate
2014-10-07 23:16:58 +02:00
/// store specified by certificateStoreName. If a path is given, the OPT_LOAD_CERT_FROM_FILE
/// option must be set.
/// * verificationMode specifies whether and how peer certificates are validated.
2014-09-05 00:17:09 +02:00
/// * options is a combination of Option flags.
/// * certificateStoreName specifies the name of the Windows certificate store
2014-10-07 23:16:58 +02:00
/// to use for loading the certificate. Predefined constants
/// CERT_STORE_MY, CERT_STORE_ROOT, etc. can be used.
2014-09-05 00:17:09 +02:00
///
2014-10-07 23:16:58 +02:00
/// Note: you can use OpenSSL to convert a certificate and private key in PEM format
/// into PKCS #12 format required to import into the Context:
///
2022-07-07 11:18:20 +02:00
/// openssl pkcs12 -export -inkey cert.key -in cert.crt -out cert.pfx
2014-09-05 00:17:09 +02:00
~ Context ( ) ;
/// Destroys the Context.
VerificationMode verificationMode ( ) const ;
/// Returns the certificate verification mode.
Usage usage ( ) const ;
/// Returns whether the context is for use by a client or by a server
/// and whether TLSv1.x is required.
bool isForServerUse ( ) const ;
/// Returns true iff the context is for use by a server.
bool sessionCacheEnabled ( ) const ;
/// Returns true iff the session cache is enabled.
2014-10-09 20:54:07 +02:00
void enableExtendedCertificateVerification ( bool flag = true ) ;
/// Enable or disable the automatic post-connection
/// extended certificate verification.
///
/// See X509Certificate::verify() for more information.
2022-07-07 11:18:20 +02:00
2014-10-09 20:54:07 +02:00
bool extendedCertificateVerificationEnabled ( ) const ;
2022-07-07 11:18:20 +02:00
/// Returns true iff automatic extended certificate
2014-10-09 20:54:07 +02:00
/// verification is enabled.
2014-09-05 00:17:09 +02:00
int options ( ) const ;
/// Returns the options flags.
void addTrustedCert ( const Poco : : Net : : X509Certificate & cert ) ;
/// Adds the certificate to the trusted certs. Takes ownership of pCert.
2020-01-10 11:41:49 +01:00
void disableProtocols ( int protocols ) ;
/// Disables the given protocols.
///
/// The protocols to be disabled are specified by OR-ing
/// values from the Protocols enumeration, e.g.:
///
/// context.disableProtocols(PROTO_SSLV2 | PROTO_SSLV3);
void requireMinimumProtocol ( Protocols protocol ) ;
/// Disables all protocol version lower than the given one.
/// To require at least TLS 1.2 or later:
///
/// context.requireMinimumProtocol(PROTO_TLSV1_2);
2014-10-07 23:16:58 +02:00
Poco : : Net : : X509Certificate certificate ( ) ;
/// Loads or imports and returns the certificate specified in the constructor.
///
/// Throws a NoCertificateException if the certificate cannot
/// be found or no certificate name has been provided in the constructor.
///
/// May also throw a filesystem-related exception if the certificate file
/// cannot be found.
2014-09-05 00:17:09 +02:00
HCERTSTORE certificateStore ( ) const ;
/// Returns a handle to the certificate store.
2014-10-07 23:16:58 +02:00
CredHandle & credentials ( ) ;
/// Returns a reference to the Schannel credentials for this Context.
2014-09-05 00:17:09 +02:00
static const std : : string CERT_STORE_MY ;
static const std : : string CERT_STORE_ROOT ;
static const std : : string CERT_STORE_TRUST ;
static const std : : string CERT_STORE_CA ;
static const std : : string CERT_STORE_USERDS ;
2014-10-07 23:16:58 +02:00
protected :
void init ( ) ;
void loadCertificate ( ) ;
void importCertificate ( ) ;
void importCertificate ( const char * pBuffer , std : : size_t size ) ;
void acquireSchannelCredentials ( CredHandle & credHandle ) const ;
DWORD proto ( ) const ;
2020-01-10 11:41:49 +01:00
DWORD enabledProtocols ( ) const ;
2014-10-07 23:16:58 +02:00
2014-09-05 00:17:09 +02:00
private :
Context ( const Context & ) ;
2014-10-07 23:16:58 +02:00
Context & operator = ( const Context & ) ;
2014-09-05 00:17:09 +02:00
Usage _usage ;
Context : : VerificationMode _mode ;
int _options ;
2020-01-10 11:41:49 +01:00
int _disabledProtocols ;
2014-10-09 20:54:07 +02:00
bool _extendedCertificateVerification ;
2014-10-07 23:16:58 +02:00
std : : string _certNameOrPath ;
std : : string _certStoreName ;
2014-09-05 00:17:09 +02:00
HCERTSTORE _hMemCertStore ;
HCERTSTORE _hCollectionCertStore ;
HCERTSTORE _hRootCertStore ;
2014-10-07 23:16:58 +02:00
HCERTSTORE _hCertStore ;
PCCERT_CONTEXT _pCert ;
CredHandle _hCreds ;
SecurityFunctionTableW & _securityFunctions ;
mutable Poco : : FastMutex _mutex ;
2014-09-05 00:17:09 +02:00
} ;
//
// inlines
//
inline Context : : VerificationMode Context : : verificationMode ( ) const
{
return _mode ;
}
inline Context : : Usage Context : : usage ( ) const
{
return _usage ;
}
inline int Context : : options ( ) const
{
return _options ;
}
inline bool Context : : isForServerUse ( ) const
{
return _usage = = SERVER_USE
2020-01-10 11:41:49 +01:00
| | _usage = = TLS_SERVER_USE
2014-09-05 00:17:09 +02:00
| | _usage = = TLSV1_SERVER_USE
| | _usage = = TLSV1_1_SERVER_USE
2020-01-10 11:41:49 +01:00
| | _usage = = TLSV1_2_SERVER_USE
| | _usage = = TLSV1_3_SERVER_USE ;
2014-09-05 00:17:09 +02:00
}
2014-10-09 20:54:07 +02:00
inline bool Context : : extendedCertificateVerificationEnabled ( ) const
{
return _extendedCertificateVerification ;
}
2014-09-05 00:17:09 +02:00
inline bool Context : : sessionCacheEnabled ( ) const
{
2014-10-09 20:54:07 +02:00
return true ;
/// Session cache is always enabled with Schannel.
2014-09-05 00:17:09 +02:00
}
inline HCERTSTORE Context : : certificateStore ( ) const
{
return _hCollectionCertStore ;
}
} } // namespace Poco::Net
# endif // NetSSL_Context_INCLUDED