diff --git a/NetSSL_OpenSSL/include/Poco/Net/Context.h b/NetSSL_OpenSSL/include/Poco/Net/Context.h index fc0ace5859..d505d86045 100644 --- a/NetSSL_OpenSSL/include/Poco/Net/Context.h +++ b/NetSSL_OpenSSL/include/Poco/Net/Context.h @@ -28,6 +28,11 @@ #include "Poco/SharedPtr.h" #include "Poco/AutoPtr.h" #include + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif + #include @@ -141,6 +146,11 @@ class NetSSL_API Context: public Poco::RefCountedObject Params(); /// Initializes the struct with default values. +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + std::string providerName; + OSSL_LIB_CTX *libctx = nullptr; +#endif + std::string privateKeyFile; /// Path to the private key file used for encryption. /// Can be empty if no private key file is used. @@ -270,6 +280,46 @@ class NetSSL_API Context: public Poco::RefCountedObject /// Note that a private key and/or certificate must be specified with /// usePrivateKey()/useCertificate() before the Context can be used. +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + Context( Usage usage, + OSSL_LIB_CTX *libctx, + const std::string &provider, + VerificationMode verificationMode = VERIFY_RELAXED, + int verificationDepth = 9, + bool loadDefaultCAs = false, + const std::string &cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH" ); + /// Creates a Context. + /// + /// * usage specifies whether the context is used by a client or server. + /// * libctx pointer to OpenSSL library context (i.e. from OSSL_LIB_CTX_new) + /// * provider specifies the custom provider query string + /// * verificationMode specifies whether and how peer certificates are validated. + /// * verificationDepth sets the upper limit for verification chain sizes. Verification + /// will fail if a certificate chain larger than this is encountered. + /// * loadDefaultCAs specifies whether the builtin CA certificates from OpenSSL are used. + /// * cipherList specifies the supported ciphers in OpenSSL notation. + /// + /// Note that a private key and/or certificate must be specified with + /// usePrivateKey()/useCertificate() or loaded through a registered provider before the Context can be used. + /// + /// Example usage: + /// * // Create a OpenSSL libary context and set default provider library search path. + /// * auto ctx = OSSL_LIB_CTX_new(); + /// * OSSL_PROVIDER_set_default_search_path( ctx, "" ); + /// * + /// * // Load providers + /// * auto provider = OSSL_PROVIDER_load( ctx, "" ); + /// * auto providerDefault = OSSL_PROVIDER_load( ctx, "default" ); + /// * + /// * // Create context to be used by server. + /// * auto serverCtx = new Poco::Net::Context( Poco::Net::Context::SERVER_USE, ctx, "", Poco::Net::Context::VERIFY_STRICT ); + /// * ... + /// * // clean-up + /// * OSSL_PROVIDER_unload( provider ); + /// * OSSL_PROVIDER_unload( providerDefault ); + /// * OSSL_LIB_CTX_free( ctx ); +#endif + ~Context(); /// Destroys the Context. @@ -465,7 +515,7 @@ class NetSSL_API Context: public Poco::RefCountedObject /// Initializes the Context with Elliptic-Curve Diffie-Hellman key /// exchange curve parameters. - void createSSLContext(); + void createSSLContext( const Params ¶ms ); /// Create a SSL_CTX object according to Context configuration. Usage _usage; diff --git a/NetSSL_OpenSSL/src/Context.cpp b/NetSSL_OpenSSL/src/Context.cpp index 42c6b815e1..fb00edfa7b 100644 --- a/NetSSL_OpenSSL/src/Context.cpp +++ b/NetSSL_OpenSSL/src/Context.cpp @@ -47,6 +47,9 @@ Context::Params::Params(): cipherList("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"), dhUse2048Bits(false), securityLevel(SECURITY_LEVEL_NONE) +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + ,libctx(0) +#endif { } @@ -112,6 +115,36 @@ Context::Context( } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + +Context::Context( + Usage usage, + OSSL_LIB_CTX *libctx, + const std::string &provider, + VerificationMode verificationMode, + int verificationDepth, + bool loadDefaultCAs, + const std::string &cipherList ) : + _usage( usage ), + _mode( verificationMode ), + _pSSLContext( 0 ), + _extendedCertificateVerification( true ), + _ocspStaplingResponseVerification( false ) +{ + Params params; + params.providerName = provider; + params.libctx = libctx; + params.verificationMode = verificationMode; + params.verificationDepth = verificationDepth; + params.loadDefaultCAs = loadDefaultCAs; + params.cipherList = cipherList; + + init( params ); +} + +#endif + + Context::~Context() { try @@ -130,7 +163,7 @@ void Context::init(const Params& params) { Poco::Crypto::OpenSSLInitializer::initialize(); - createSSLContext(); + createSSLContext( params ); try { @@ -533,14 +566,21 @@ void Context::setInvalidCertificateHandler(InvalidCertificateHandlerPtr pInvalid } -void Context::createSSLContext() +void Context::createSSLContext( const Params ¶ms ) { int minTLSVersion = 0; if (SSLManager::isFIPSEnabled()) { -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - _pSSLContext = SSL_CTX_new(TLS_method()); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_method() ); + } +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_method() ); #else _pSSLContext = SSL_CTX_new(TLSv1_method()); #endif @@ -551,8 +591,17 @@ void Context::createSSLContext() { case CLIENT_USE: case TLS_CLIENT_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - _pSSLContext = SSL_CTX_new(TLS_client_method()); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_client_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_client_method() ); + } + + minTLSVersion = TLS1_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_client_method() ); minTLSVersion = TLS1_VERSION; #else _pSSLContext = SSL_CTX_new(SSLv23_client_method()); @@ -561,8 +610,17 @@ void Context::createSSLContext() case SERVER_USE: case TLS_SERVER_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - _pSSLContext = SSL_CTX_new(TLS_server_method()); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_server_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_server_method() ); + } + + minTLSVersion = TLS1_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_server_method() ); minTLSVersion = TLS1_VERSION; #else _pSSLContext = SSL_CTX_new(SSLv23_server_method()); @@ -570,8 +628,17 @@ void Context::createSSLContext() break; case TLSV1_CLIENT_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - _pSSLContext = SSL_CTX_new(TLS_client_method()); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_client_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_client_method() ); + } + + minTLSVersion = TLS1_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_client_method() ); minTLSVersion = TLS1_VERSION; #else _pSSLContext = SSL_CTX_new(TLSv1_client_method()); @@ -579,8 +646,17 @@ void Context::createSSLContext() break; case TLSV1_SERVER_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - _pSSLContext = SSL_CTX_new(TLS_server_method()); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_server_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_server_method() ); + } + + minTLSVersion = TLS1_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_server_method() ); minTLSVersion = TLS1_VERSION; #else _pSSLContext = SSL_CTX_new(TLSv1_server_method()); @@ -593,8 +669,17 @@ void Context::createSSLContext() * if TLS1.x was removed at OpenSSL library build time via Configure options. */ case TLSV1_1_CLIENT_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - _pSSLContext = SSL_CTX_new(TLS_client_method()); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_client_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_client_method() ); + } + + minTLSVersion = TLS1_1_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_client_method() ); minTLSVersion = TLS1_1_VERSION; #else _pSSLContext = SSL_CTX_new(TLSv1_1_client_method()); @@ -602,8 +687,17 @@ void Context::createSSLContext() break; case TLSV1_1_SERVER_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - _pSSLContext = SSL_CTX_new(TLS_server_method()); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_server_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_server_method() ); + } + + minTLSVersion = TLS1_1_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_server_method() ); minTLSVersion = TLS1_1_VERSION; #else _pSSLContext = SSL_CTX_new(TLSv1_1_server_method()); @@ -613,18 +707,36 @@ void Context::createSSLContext() #if defined(SSL_OP_NO_TLSv1_2) && !defined(OPENSSL_NO_TLS1) case TLSV1_2_CLIENT_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - _pSSLContext = SSL_CTX_new(TLS_client_method()); - minTLSVersion = TLS1_2_VERSION; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_client_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_client_method() ); + } + + minTLSVersion = TLS1_2_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_client_method() ); + minTLSVersion = TLS1_2_VERSION; #else _pSSLContext = SSL_CTX_new(TLSv1_2_client_method()); #endif break; case TLSV1_2_SERVER_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - _pSSLContext = SSL_CTX_new(TLS_server_method()); - minTLSVersion = TLS1_2_VERSION; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_server_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_server_method() ); + } + + minTLSVersion = TLS1_2_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_server_method() ); + minTLSVersion = TLS1_2_VERSION; #else _pSSLContext = SSL_CTX_new(TLSv1_2_server_method()); #endif @@ -633,16 +745,34 @@ void Context::createSSLContext() #if defined(SSL_OP_NO_TLSv1_3) && !defined(OPENSSL_NO_TLS1) case TLSV1_3_CLIENT_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10101000L - _pSSLContext = SSL_CTX_new(TLS_client_method()); - minTLSVersion = TLS1_3_VERSION; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_client_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_client_method() ); + } + + minTLSVersion = TLS1_3_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10101000L + _pSSLContext = SSL_CTX_new( TLS_client_method() ); + minTLSVersion = TLS1_3_VERSION; #endif break; case TLSV1_3_SERVER_USE: -#if OPENSSL_VERSION_NUMBER >= 0x10101000L - _pSSLContext = SSL_CTX_new(TLS_server_method()); - minTLSVersion = TLS1_3_VERSION; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ( nullptr != params.libctx && !params.providerName.empty() ) { + _pSSLContext = SSL_CTX_new_ex( params.libctx, params.providerName.c_str(), TLS_server_method() ); + } + else { + _pSSLContext = SSL_CTX_new( TLS_server_method() ); + } + + minTLSVersion = TLS1_3_VERSION; +#elif OPENSSL_VERSION_NUMBER >= 0x10100000L + _pSSLContext = SSL_CTX_new( TLS_server_method() ); + minTLSVersion = TLS1_3_VERSION; #endif break; #endif