在某些机器上使用静态链接的 OpenSSL 3.0.8 时,无法加载旧提供程序

问题描述 投票:0回答:1

背景

我有一个使用 OpenSsl 1.1.1t 的大型 C++ 项目,现在我正在调整它以使用 OpenSsl 3.0.8。

为了解决加载旧 pfx 文件的一些问题,我需要加载旧提供程序。

问题

以下代码在我的本地计算机(Win10)上成功:

OpenSslProviderHandler::OpenSslProviderHandler(IReporting* reporter, OSSL_LIB_CTX* ctx)
{
    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, nullptr);

    m_defaultProvider = OSSL_PROVIDER_load(ctx, "default");
    if (m_defaultProvider == nullptr)
    {
        reporter->reportCritical(makeSslError(), "Failed to load the default provider");
    }

    m_legacyProvider = OSSL_PROVIDER_load(ctx, "legacy");
    if (m_legacyProvider == nullptr)
    {
        reporter->reportCritical(makeSslError(), "Failed to load the legacy provider");
    }
}

没有记录任何内容。

在测试机器(Win10、Jenkins)上,相同的测试失败。在日志中我可以看到这个严重错误报告:

Failed to load the legacy provider. could not load the shared library (DSO support routines) [asio.ssl:310378599]

然后尝试从 pfx 文件加载私钥失败:“不支持(数字信封例程)[asio.ssl:50856204]”。

在我的本地计算机上,我检查了上面显示的代码是否加载了一些新的 dll,但是执行此代码之前和之后加载的 dll 列表是相同的。

技术笔记

OpenSsl 是由以下脚本构建的:

perl Configure debug-VC-WIN64A no-asm enable-static-engine no-shared no-tests no-nod-module --prefix="%cd%\%INSTALL_PREFIX%" --openssldir="%cd%\x64\Debug" -FS || exit /b 1

perl -i.bak -pe "s/^\s*@\s*$/    @\$(ECHO\)\n/g" makefile || exit /b 1

nmake -k all  || exit /b 1

nmake install_sw install_ssldirs || exit /b 1

~~这是我的程序在本地计算机上运行时加载的 dll 列表:~~ 抱歉,这个列表不正确,我误用了“资源监视器”来获取进程加载的库列表。当我注意到我发现legacy.dll已加载时

ADVAPI32.dll    10.0.19041.3693 C:\WINDOWS\System32\ADVAPI32.dll
bcrypt.dll  10.0.19041.3636 C:\WINDOWS\System32\bcrypt.dll
combase.dll 10.0.19041.3636 C:\WINDOWS\System32\combase.dll
CRYPT32.dll 10.0.19041.3636 C:\WINDOWS\System32\CRYPT32.dll
CRYPTBASE.DLL   10.0.19041.3636 C:\WINDOWS\SYSTEM32\CRYPTBASE.DLL
dbgeng.dll  10.0.19041.3636 C:\WINDOWS\SYSTEM32\dbgeng.dll
dbghelp.dll 10.0.19041.3636 C:\WINDOWS\SYSTEM32\dbghelp.dll
dbgmodel.dll    10.0.19041.3636 C:\WINDOWS\SYSTEM32\dbgmodel.dll
DPAPI.DLL   10.0.19041.3636 C:\WINDOWS\SYSTEM32\DPAPI.DLL
GDI32.dll   10.0.19041.3636 C:\WINDOWS\System32\GDI32.dll
gdi32full.dll   10.0.19041.3636 C:\WINDOWS\System32\gdi32full.dll
IMM32.DLL   10.0.19041.3636 C:\WINDOWS\System32\IMM32.DLL
KERNEL32.DLL    10.0.19041.3636 C:\WINDOWS\System32\KERNEL32.DLL
KERNELBASE.dll  10.0.19041.3636 C:\WINDOWS\System32\KERNELBASE.dll
MPR.dll 10.0.19041.3636 C:\WINDOWS\SYSTEM32\MPR.dll
msi.dll 5.0.19041.3636  C:\WINDOWS\SYSTEM32\msi.dll
msvcp_win.dll   10.0.19041.3636 C:\WINDOWS\System32\msvcp_win.dll
msvcrt.dll  7.0.19041.3636  C:\WINDOWS\System32\msvcrt.dll
MSWSOCK.dll 10.0.19041.3636 C:\WINDOWS\SYSTEM32\MSWSOCK.dll
NETAPI32.dll    10.0.19041.3636 C:\WINDOWS\SYSTEM32\NETAPI32.dll
ntdll.dll   10.0.19041.3636 C:\WINDOWS\SYSTEM32\ntdll.dll
ODBC32.dll  10.0.19041.3636 C:\WINDOWS\SYSTEM32\ODBC32.dll
ole32.dll   10.0.19041.3636 C:\WINDOWS\System32\ole32.dll
OLEAUT32.dll    10.0.19041.3636 C:\WINDOWS\System32\OLEAUT32.dll
RPCRT4.dll  10.0.19041.3636 C:\WINDOWS\System32\RPCRT4.dll
sechost.dll 10.0.19041.3636 C:\WINDOWS\System32\sechost.dll
SHELL32.dll 10.0.19041.3636 C:\WINDOWS\System32\SHELL32.dll
SRVCLI.DLL  10.0.19041.3636 C:\WINDOWS\SYSTEM32\SRVCLI.DLL
ucrtbase.dll    10.0.19041.3636 C:\WINDOWS\System32\ucrtbase.dll
USER32.dll  10.0.19041.3636 C:\WINDOWS\System32\USER32.dll
USERENV.dll 10.0.19041.3636 C:\WINDOWS\SYSTEM32\USERENV.dll
VERSION.dll 10.0.19041.3636 C:\WINDOWS\SYSTEM32\VERSION.dll
win32u.dll  10.0.19041.3636 C:\WINDOWS\System32\win32u.dll
WLDAP32.dll 10.0.19041.3636 C:\WINDOWS\System32\WLDAP32.dll
WS2_32.dll  10.0.19041.3636 C:\WINDOWS\System32\WS2_32.dll
XmlLite.dll 10.0.19041.3636 C:\WINDOWS\SYSTEM32\XmlLite.dll

问题

  • 此错误的根源是什么?
  • 我的本地计算机和测试计算机(Jenkins)上的 Win10 差异可能是什么,导致不同的行为(加载旧提供程序成功或失败)?测试机是小型虚拟Win10机器,所需软件最少。
  • 是否涉及一些实际的dll?哪一个?
  • 或者是否还有其他根本原因导致旧提供程序无法在其他系统上加载?
c windows openssl
1个回答
0
投票

根本原因

好的,我发现问题了。问题是共享库隐藏在构建 OpenSsl 的地方。正好在路径

<build prefix>\lib\ossl-modules\legacy.dll

在我的本地计算机上它正在工作,因为测试是在构建产品的同一台计算机上运行的。

在 Jenkins 上它失败了,因为测试是在测试机器上运行的(多个配置),并且我的产品从构建机器(docker)复制到测试机器(具有所需软件的虚拟机)。复制的内容未覆盖 OpenSsl 构建位置。

修复

现在很长一段时间以来,我一直在寻找如何使遗留提供程序成为 OpenSsl 库的一部分,结果发现您只需向

Configure
步骤添加一个参数:
no-module
,整个问题就已经解决了:

perl Configure debug-VC-WIN64A no-asm enable-static-engine no-shared no-tests no-nod-module no-module --prefix="%cd%\%INSTALL_PREFIX%" --openssldir="%cd%\x64\Debug" -FS || exit /b 1

免责声明:

no-nod-module
参数只是我公司某种OpenSsl fork的结果(细节并不重要)。

© www.soinside.com 2019 - 2024. All rights reserved.