静态链接OpenSSL 3.0.8时部分Win10机器无法加载Legacy Provider的问题排查求助
静态链接OpenSSL 3.0.8时部分Win10机器无法加载Legacy Provider的问题排查求助
背景
我手头有一个大型C++项目,之前一直用OpenSSL 1.1.1t,现在正在迁移适配OpenSSL 3.0.8。因为要处理旧的PFX文件,必须加载Legacy Provider才能解决兼容性问题。
问题现象
下面这段代码在我本地的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文件加载私钥时也跟着失败,错误信息是:
"unsupported (digital envelope routines) [asio.ssl:50856204]"
一开始我在本地机器上检查这段代码执行前后的DLL加载列表,误以为没有变化,后来纠正了排查方式,发现本地实际加载了<OpenSsl build prefix>\lib\ossl-modules\legacy.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列表如下:
- 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
我的疑问
- 这个错误的根源可能是什么?
- 本地Win10机器和测试机(Jenkins)之间的哪些差异会导致Legacy Provider加载结果不同?测试机是一个仅安装了必要软件的精简Win10虚拟机。
- 是否确实有某个DLL是关键因素?具体是哪一个?
- 有没有其他可能的原因导致Legacy Provider在测试机上无法加载?
备注:内容来源于stack exchange,提问作者Marek R




