2

I am stucked with the following issue, when I try to initialize the SSL functionality using Poco's Crypto Poco::Crypto::initializeCrypto();. The issue is that in the machine where I perform the build, it works fine, but in other machines, a Poco::Exception is thrown Crypto Exception: Failed to load OpenSSL legacy provider.

My development environment is the following:

I have built a simple Windows console application, to isolate the issue, the code is the following:

#include <iostream>
//#include <Poco/Net/NetSSL.h>
#include <Poco/Crypto/Crypto.h>
#include <Poco/Exception.h>
#include <string>

int main()
{
    try
    {
        std::cout << "Initializing Poco Ssl." << std::endl;

        Poco::Crypto::initializeCrypto();
        //Poco::Net::initializeSSL();
    }
    catch (const Poco::Exception & e)
    {
        std::cout << "Exception initializing Poco Ssl library." << std::endl;
        std::cout << e.displayText() << std::endl;
    }

    std::string sTmp;
    std::getline(std::cin, sTmp);
}
  • I am using MSVC (Visual Studio 2019) compiler tools.
  • I am consuming POCO library using Vcpkg.
  • If I run vcpkg list, I obtain the following output.
C:\workcopy\vcpkg>vcpkg list

brotli:x64-windows 1.0.9#5 a generic-purpose lossless compression algorithm...
bzip2:x64-windows 1.0.8#4 bzip2 is a freely available, patent free, high-q...
bzip2:x64-windows-static 1.0.8#4 bzip2 is a freely available, patent free, high-q...
bzip2[tool]:x64-windows Builds bzip2 executable
bzip2[tool]:x64-windows-static Builds bzip2 executable
curl:x64-windows 8.0.1 A library for transferring data with URLs
curl[non-http]:x64-windows Enables protocols beyond HTTP/HTTPS/HTTP2
curl[schannel]:x64-windows SSL support (Secure Channel)
curl[ssl]:x64-windows Default SSL backend
curl[sspi]:x64-windows SSPI support
egl-registry:x64-windows 2022-09-20 the EGL API and Extension Registry
expat:x64-windows 2.5.0#3 XML parser library written in C
expat:x64-windows-static 2.5.0#3 XML parser library written in C
freetype:x64-windows 2.12.1#3 A library to render fonts.
freetype[brotli]:x64-windows Support decompression of WOFF2 streams
freetype[bzip2]:x64-windows Support bzip2 compressed fonts.
freetype[png]:x64-windows Support PNG compressed OpenType embedded bitmaps.
freetype[zlib]:x64-windows Use zlib instead of internal library for DEFLATE
ftgl:x64-windows 2022-05-18#1 FTGL is a free open source library to enable dev...
libpng:x64-windows 1.6.39#1 libpng is a library implementing an interface fo...
opengl-registry:x64-windows 2022-09-29#1 the API and Extension registries for the OpenGL ...
opengl:x64-windows 2022-12-04#3 Open Graphics Library (OpenGL)[3][4][5] is a cro...
openssl:x64-windows 3.1.0#2 OpenSSL is an open source project that provides ...
openssl:x64-windows-static 3.1.0#2 OpenSSL is an open source project that provides ...
pcre2:x64-windows 10.40#1 Regular Expression pattern matching using the sa...
pcre2:x64-windows-static 10.40#1 Regular Expression pattern matching using the sa...
poco:x64-windows 1.12.4#4 Modern, powerful open source C++ class libraries...
poco:x64-windows-static 1.12.4#4 Modern, powerful open source C++ class libraries...
poco[crypto]:x64-windows Crypto support
poco[crypto]:x64-windows-static Crypto support
poco[netssl]:x64-windows NetSSL support for POCO
poco[netssl]:x64-windows-static NetSSL support for POCO
sentry-native:x64-windows 0.6.1 Sentry SDK for C, C++ and native applications.
sentry-native[backend]:x64-windows Enables the platform-specific backend.
sentry-native[transport]:x64-windows Enables the platform-specific network transport.
vcpkg-cmake-config:x64-windows 2022-02-06#1
vcpkg-cmake-get-vars:x64-windows 2023-03-02
vcpkg-cmake:x64-windows 2022-12-22
zlib:x64-windows 1.2.13 A compression library
zlib:x64-windows-static 1.2.13 A compression library

I have tried using the following code snippet to initialize OpenSSL, but fails with the same exception in the first line.

Poco::Crypto::OpenSSLInitializer openSSLInitializer;
try {
{
        Poco::Path cPath(getApplicationPath());
        cPath.makeDirectory();
        OSSL_PROVIDER_set_default_search_path(NULL, cPath.toString().c_str());
    }
        OSSL_PROVIDER* legacy = NULL;
    OSSL_PROVIDER* deflt = NULL;
    if ((legacy == nullptr) && (OSSL_PROVIDER_available(NULL, "legacy") == 0)) {
        legacy = OSSL_PROVIDER_try_load(NULL, "legacy", 1);
    }
    if (deflt == nullptr) {
        deflt = OSSL_PROVIDER_load(NULL, "default");
    }
}
catch (Poco::Exception& exc) {
}

Furthermore I have discovered the problem is the application depends on the absolute path to \vcpkg\packages\openssl_x64-windows\bin\legacy.dll, because if i rename the legacy.dll file to _legacy.dll, it throws the same exception, even in the same machine where i perform the build.

I have even tried to manually copy legacy.dll to the same directory as the exectuable, and it doesn't work.

So, how could I configure the project to include this needed dll during the building process?

If you need further details, I can provide them. Thank you in advance!

  • On the target machine are you able to run the openssl comand line app? If so what is the value returned by running `openssl version -m`? – Matt Caswell May 05 '23 at 14:02

1 Answers1

1

Thanks to @micheleselea, from Poco's Github project I managed to solve the issue.

The problem was related to a runtime dependency with OpenSSL's legacy DLL. I could load this DLL when starting my application, and then I was able to successfully load the OpenSSL machinery using Poco::Crypto's methods.

Here's a code snippet to solve the issue.

int main()
{
try
{
        std::cout << "Initializing OpenSsl provider." << std::endl;
    {
        Poco::Path cPath("C:\\workcopy\\PLAYGROUND\\PocoFailedLoadOpenSSL\\x64\\Release\\");
        cPath.makeDirectory();
        OSSL_PROVIDER_set_default_search_path(NULL, cPath.toString().c_str());
    }
    OSSL_PROVIDER* legacy = NULL;
    if ((legacy == nullptr) && (OSSL_PROVIDER_available(NULL, "legacy") == 0))
        legacy = OSSL_PROVIDER_try_load(NULL, "legacy", 1);
}
catch (Poco::Exception & e)
{
    std::cout << "Exception initializing OpenSsl provider." << std::endl;
    std::cout << e.displayText() << std::endl;
}
try
{
    std::cout << "Initializing Poco Ssl." << std::endl;
    Poco::Crypto::OpenSSLInitializer openSSLInitializer;
}
catch (const Poco::Exception & e)
{
    std::cout << "Exception initializing Poco Ssl library." << std::endl;
    std::cout << e.displayText() << std::endl;
}

std::string sTmp;
std::getline(std::cin, sTmp);
}