You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by iv...@apache.org on 2022/01/20 12:25:33 UTC

[ignite] branch master updated: IGNITE-15353 CPP: Fix OpenSSL shared library load order, add OpenSSL 3.0.x support - Fixes #9750.

This is an automated email from the ASF dual-hosted git repository.

ivandasch pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 4a90246  IGNITE-15353 CPP: Fix OpenSSL shared library load order, add OpenSSL 3.0.x support - Fixes #9750.
4a90246 is described below

commit 4a9024670e64f2bbb69d5c873f12ffcfed28164a
Author: ivandasch@apache.org <Ivan Daschinsky>
AuthorDate: Thu Jan 20 15:24:30 2022 +0300

    IGNITE-15353 CPP: Fix OpenSSL shared library load order, add OpenSSL 3.0.x support - Fixes #9750.
    
    Signed-off-by: Ivan Daschinsky <iv...@apache.org>
---
 .../cpp/common/include/ignite/common/utils.h       |   2 +-
 modules/platforms/cpp/common/src/common/utils.cpp  |   2 +-
 .../network/src/network/ssl/secure_data_filter.cpp |   2 +-
 .../cpp/network/src/network/ssl/ssl_gateway.cpp    | 124 ++++++++++++++-------
 .../cpp/network/src/network/ssl/ssl_gateway.h      |  13 ++-
 5 files changed, 96 insertions(+), 47 deletions(-)

diff --git a/modules/platforms/cpp/common/include/ignite/common/utils.h b/modules/platforms/cpp/common/include/ignite/common/utils.h
index f516ffc..e440e7d 100644
--- a/modules/platforms/cpp/common/include/ignite/common/utils.h
+++ b/modules/platforms/cpp/common/include/ignite/common/utils.h
@@ -654,7 +654,7 @@ namespace ignite
          * @param name Name without extension.
          * @return Full name.
          */
-        IGNITE_IMPORT_EXPORT std::string GetDynamicLibraryName(const char* name);
+        IGNITE_IMPORT_EXPORT std::string GetDynamicLibraryName(const std::string& name);
 
         /**
          * Get hex dump of binary data in string form.
diff --git a/modules/platforms/cpp/common/src/common/utils.cpp b/modules/platforms/cpp/common/src/common/utils.cpp
index 28433e82..dba7e55 100644
--- a/modules/platforms/cpp/common/src/common/utils.cpp
+++ b/modules/platforms/cpp/common/src/common/utils.cpp
@@ -195,7 +195,7 @@ namespace ignite
             return CTimeToTimestamp(localTime, ns);
         }
 
-        IGNITE_IMPORT_EXPORT std::string GetDynamicLibraryName(const char* name)
+        IGNITE_IMPORT_EXPORT std::string GetDynamicLibraryName(const std::string& name)
         {
             std::stringstream libNameBuffer;
 
diff --git a/modules/platforms/cpp/network/src/network/ssl/secure_data_filter.cpp b/modules/platforms/cpp/network/src/network/ssl/secure_data_filter.cpp
index 02b1c50..b0f30f6 100644
--- a/modules/platforms/cpp/network/src/network/ssl/secure_data_filter.cpp
+++ b/modules/platforms/cpp/network/src/network/ssl/secure_data_filter.cpp
@@ -116,7 +116,7 @@ namespace ignite
                     throw IgniteError(IgniteError::IGNITE_ERR_SECURE_CONNECTION_FAILURE, "Can not get SSL method");
 
                 SSL_CTX* sslContext0 = sslGateway.SSL_CTX_new_(method);
-                if (!sslContext)
+                if (!sslContext0)
                     throw IgniteError(IgniteError::IGNITE_ERR_SECURE_CONNECTION_FAILURE,
                         "Can not create new SSL context");
 
diff --git a/modules/platforms/cpp/network/src/network/ssl/ssl_gateway.cpp b/modules/platforms/cpp/network/src/network/ssl/ssl_gateway.cpp
index 33377b9..f55ce8c 100644
--- a/modules/platforms/cpp/network/src/network/ssl/ssl_gateway.cpp
+++ b/modules/platforms/cpp/network/src/network/ssl/ssl_gateway.cpp
@@ -66,34 +66,25 @@ namespace ignite
                 memset(&functions, 0, sizeof(functions));
             }
 
-            common::dynamic::Module SslGateway::LoadSslLibrary(const char* name)
+            common::dynamic::Module SslGateway::LoadSslLibrary(const std::string& name, const std::string& homeDir)
             {
                 using namespace common;
                 using namespace dynamic;
 
-                std::string home = GetEnv(ADDITIONAL_OPENSSL_HOME_ENV);
-
-                if (home.empty())
-                    home = GetEnv("OPENSSL_HOME");
-
                 std::string fullName = GetDynamicLibraryName(name);
 
-                if (!home.empty())
+                if (!homeDir.empty())
                 {
-                    const char* paths[] = {"bin", "lib"};
-
-                    for (size_t i = 0; i < 2; i++) {
-                        std::stringstream constructor;
-
-                        constructor << home << Fs << paths[i] << Fs << fullName;
-
-                        std::string fullPath = constructor.str();
+#ifdef _WIN32
+                    const char* binSubDir = "bin";
+#else
+                    const char* binSubDir = "lib";
+#endif
+                    std::ostringstream oss;
 
-                        Module mod = LoadModule(fullPath);
+                    oss << homeDir << Fs << binSubDir << Fs << fullName;
 
-                        if (mod.IsLoaded())
-                            return mod;
-                    }
+                    return LoadModule(oss.str());
                 }
 
                 return LoadModule(fullName);
@@ -101,40 +92,85 @@ namespace ignite
 
             void SslGateway::LoadSslLibraries()
             {
-                libssl = LoadSslLibrary("libssl");
+                using namespace common;
 
-                if (!libssl.IsLoaded())
-                {
-                    libcrypto = LoadSslLibrary("libcrypto-1_1-x64");
-                    libssl = LoadSslLibrary("libssl-1_1-x64");
-                }
+                std::string home = GetEnv(ADDITIONAL_OPENSSL_HOME_ENV);
+                if (home.empty())
+                    home = GetEnv("OPENSSL_HOME");
 
-                if (!libssl.IsLoaded())
-                {
-                    libeay32 = LoadSslLibrary("libeay32");
-                    ssleay32 = LoadSslLibrary("ssleay32");
-                }
+                bool isLoaded = false;
 
-                if (!libssl.IsLoaded() && (!libeay32.IsLoaded() || !ssleay32.IsLoaded()))
-                {
-                    if (!libssl.IsLoaded())
-                        throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
-                            "Can not load neccessary OpenSSL library: libssl");
+                if (!home.empty())
+                    isLoaded = TryLoadSslLibraries(home);
+
+                // Try load from system path.
+                if (!isLoaded)
+                    isLoaded = TryLoadSslLibraries("");
 
+                if (!isLoaded)
+                {
+#ifdef _WIN32
                     std::stringstream ss;
 
-                    ss << "Can not load neccessary OpenSSL libraries:";
+                    ss << "Can not load necessary OpenSSL libraries:";
+
+                    if (!libssl.IsLoaded() || !libcrypto.IsLoaded())
+                    {
+                        if (!libssl.IsLoaded())
+                            ss << " libssl";
 
-                    if (!libeay32.IsLoaded())
-                        ss << " libeay32";
+                        if (!libcrypto.IsLoaded())
+                            ss << " libcrypto";
+                    }
+                    else
+                    {
+                        if (!libeay32.IsLoaded())
+                            ss << " libeay32";
 
-                    if (!ssleay32.IsLoaded())
-                        ss << " ssleay32";
+                        if (!ssleay32.IsLoaded())
+                            ss << " ssleay32";
+                    }
 
                     std::string res = ss.str();
 
                     throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, res.c_str());
+#else
+                    if (!libssl.IsLoaded())
+                        throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                            "Can not load necessary OpenSSL library: libssl");
+#endif
+                }
+            }
+
+            bool SslGateway::TryLoadSslLibraries(const std::string& homeDir)
+            {
+#ifdef _WIN32
+#ifdef _WIN64
+#define SSL_LIB_PLATFORM_POSTFIX "-x64"
+#else
+#define SSL_LIB_PLATFORM_POSTFIX ""
+#endif
+                libcrypto = LoadSslLibrary("libcrypto-3" SSL_LIB_PLATFORM_POSTFIX, homeDir);
+                libssl = LoadSslLibrary("libssl-3" SSL_LIB_PLATFORM_POSTFIX, homeDir);
+
+                if (!libssl.IsLoaded() || !libcrypto.IsLoaded())
+                {
+                    libcrypto = LoadSslLibrary("libcrypto-1_1" SSL_LIB_PLATFORM_POSTFIX, homeDir);
+                    libssl = LoadSslLibrary("libssl-1_1" SSL_LIB_PLATFORM_POSTFIX, homeDir);
+                }
+
+                if (!libssl.IsLoaded() || !libcrypto.IsLoaded())
+                {
+                    libeay32 = LoadSslLibrary("libeay32", homeDir);
+                    ssleay32 = LoadSslLibrary("ssleay32", homeDir);
                 }
+
+                return (libssl.IsLoaded() && libcrypto.IsLoaded()) || (libeay32.IsLoaded() && ssleay32.IsLoaded());
+#else
+                libssl = LoadSslLibrary("libssl", homeDir);
+
+                return libssl.IsLoaded();
+#endif
             }
 
             void SslGateway::LoadMandatoryMethods()
@@ -166,7 +202,11 @@ namespace ignite
 
                 functions.fpSSL_get_verify_result = LoadSslMethod("SSL_get_verify_result");
 
-                functions.fpSSL_get_peer_certificate = LoadSslMethod("SSL_get_peer_certificate");
+                functions.fpSSL_get_peer_certificate = TryLoadSslMethod("SSL_get_peer_certificate");
+                // OpenSSL >= 3.0.0
+                if (!functions.fpSSL_get_peer_certificate)
+                    functions.fpSSL_get_peer_certificate = LoadSslMethod("SSL_get1_peer_certificate");
+
                 functions.fpSSL_ctrl = LoadSslMethod("SSL_ctrl");
                 functions.fpSSL_CTX_ctrl = LoadSslMethod("SSL_CTX_ctrl");
 
@@ -275,7 +315,7 @@ namespace ignite
                 return fp;
             }
 
-            char* SslGateway::SSLeay_version_(int type)
+            char* SslGateway::OpenSSL_version_(int type)
             {
                 typedef char* (FuncType)(int);
 
diff --git a/modules/platforms/cpp/network/src/network/ssl/ssl_gateway.h b/modules/platforms/cpp/network/src/network/ssl/ssl_gateway.h
index 13326b5..5a03495 100644
--- a/modules/platforms/cpp/network/src/network/ssl/ssl_gateway.h
+++ b/modules/platforms/cpp/network/src/network/ssl/ssl_gateway.h
@@ -18,6 +18,7 @@
 #ifndef _IGNITE_NETWORK_SSL_SSL_GATEWAY
 #define _IGNITE_NETWORK_SSL_SSL_GATEWAY
 
+#include <string>
 #include <openssl/ssl.h>
 #include <openssl/conf.h>
 #include <openssl/err.h>
@@ -121,7 +122,7 @@ namespace ignite
                     return inited;
                 }
 
-                char* SSLeay_version_(int type);
+                char* OpenSSL_version_(int type);
 
                 int OPENSSL_init_ssl_(uint64_t opts, const void* settings);
 
@@ -238,9 +239,10 @@ namespace ignite
                 /**
                  * Load SSL library.
                  * @param name Name.
+                 * @param homeDir OpenSSL home directory.
                  * @return Module.
                  */
-                common::dynamic::Module LoadSslLibrary(const char* name);
+                common::dynamic::Module LoadSslLibrary(const std::string& name, const std::string& homeDir);
 
                 /**
                  * Load all SSL libraries.
@@ -248,6 +250,13 @@ namespace ignite
                 void LoadSslLibraries();
 
                 /**
+                 * Try load SSL libraries
+                 * @param homeDir OpenSSL home directory.
+                 * @return @c true on success and @c false if not.
+                 */
+                bool TryLoadSslLibraries(const std::string& homeDir);
+
+                /**
                  * Load mandatory SSL methods.
                  *
                  * @throw IgniteError if can not load one of the functions.