Background
I have complex application which uses some OpenSSL features. One of the features is possibility to read PKCS12 files. OpenSSL is statically linked and my project builds it from sources.
Problem
Currently I'm upgrading my application dependency OpenSSL form 1.1.x to 3.0.8. Happily build process was not broken, but some test detected issues. Turns out that some PKCS12 files used for testing are now not readable.
bool pfxToDer(const unsigned char* in, long size, const char* pass, .....)
{
utils::UniquePtr<PKCS12> pPkcs12; // this are my smart pointers to handle OpenSSL using C++ RAII pattern
utils::UniquePtr<EVP_PKEY> pKey;
utils::UniquePtr<X509> pCert;
d2i_PKCS12(std::out_ptr(pPkcs12), &in, size);
if (!pPkcs12)
{
debugOpenSslError();
return false;
}
const auto parsingResult = PKCS12_parse(pPkcs12.get(), pass, std::out_ptr(pKey), std::out_ptr(pCert), nullptr);
if (!parsingResult)
{
// here fails
debugOpenSslError();
return false;
}
....
PKCS12_parse
with error which is log by debugOpenSslError();
as:
errorCode = 0x0308010c description = "error:0308010C:digital envelope routines::unsupported"
With quick googling I've found this SO answer.
So looks like my test data are using some old encryption which is not considered safe anymore. I need to read this data anyway. If customer has some old data he like to import it should be possible.
I've found it should be possible to enable legacy mode and make this work. So I've added somewhere in my code:
[[maybe_unused]] auto provider = OSSL_PROVIDER_load(NULL, "legacy");
This call succeeded (it returns provider), but PKCS12_parse
keeps failing.
When I try use opessl tool built with library I'm using I've got this:
F:\repos\project\third_party\openssl\install_dir\x64\Release\bin>openssl.exe pkcs12 -in test_certs.pfx -nodes
Enter Import Password:
Error outputting keys and certificates
88940000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto\evp\evp_fetch.c:373:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()
F:\repos\project\third_party\openssl\install_dir\x64\Release\bin>openssl.exe pkcs12 -in test_certs.pfx -nodes -provider legacy
-nomacver
Enter Import Password:
Error outputting keys and certificates
D83F0000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto\evp\evp_fetch.c:373:Global default library context, Algorithm (SHA1 : 96), Properties (<null>)
D83F0000:error:030000A1:digital envelope routines:EVP_PBE_CipherInit_ex:unknown digest:crypto\evp\evp_pbe.c:143:
Questions
- Is there some way to force
PKCS12_parse
to work anyway? - is my attempt to load legacy provider a good solution? If yes why it didn't work?
- do I have to change configuration of OpenSSL build to make it work? How?
- can I get more details why exactly parsing fails? What exactly is missing?
Tech notes
This must work on Windows/Linux/MacOS
I build OpenSSL on Windows (VC-WIN32 and VC-WIN64A) this way:
perl Configure %PLATFORM% no-asm enable-static-engine no-shared no-tests no-nod-module --prefix="%cd%\%INSTALL_PREFIX%" --openssldir="%cd%\%INSTALL_PREFIX%" -FS || exit /b 1
perl -i.bak -pe "s/^\s*@\s*$/ @\$(ECHO\)\n/g" makefile || exit /b 1
nmake -k all || exit /b 1