3

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
9
  • Why did you tag this C when your code is obviously C++? Commented May 19, 2023 at 15:27
  • 1
    OpenSSL is C API. Fact that I'm calling it from C++ is not important. Commented May 19, 2023 at 15:39
  • So looks like my test data are using some old encryption which is not considered safe anymore. I need to read this data anyway Which specific "old encryption" algorithm(s)? If those algorithm(s) have been entirely removed from the OpenSSL code base, you won't be able to use OpenSSL 3.x to decrypt them. Commented May 19, 2023 at 16:36
  • 1
    This is also likely relevant: wiki.openssl.org/index.php/OpenSSL_3.0#Providers Commented May 19, 2023 at 17:26
  • 1
    @MarekR See updated information at openssl.org/docs/man3.0/man7/… Commented May 20, 2023 at 0:46

2 Answers 2

1

is my attempt to load legacy provider a good solution? If yes why it didn't work?

Partly (assuming 'somewhere in my code' is executed prior to the PKCS12_parse call). If you don't load any providers OpenSSL uses "default" by default (!), but if you do it uses ONLY the provider(s) you explicitly loaded; it does not add "default" to the call(s) you make. Since you need BOTH "default" and "legacy" providers, you need to call OSSL_PROVIDER_load on BOTH of them -- and then it works.

can I get more details why exactly parsing fails? What exactly is missing?

It looks like your debug routine is printing only the 32-bit error code and the result of decoding it with ERR_error_string. The OpenSSL error queue can also contain a sourcefile location (filename and linenumber), which usually doesn't help much more than the errorcode does, and optional 'data' (text), which is useful for SOME errors -- including this one. Plus the error queue can contain more than one entry, and in that case it is often helpful to display ALL of them; while you can code this yourself, it is easier to just call ERR_print_errors[_fp] -- see the man page, installed automatically on your system but not easily readable on Windows, or on the web.

When I try use [commandline] I've got this: ...

Similarly, for commandline you need to specify BOTH providers -provider legacy -provider default (order doesn't matter unless they conflict and these don't) or alternatively use the shorthand -legacy which sets the two providers and also sets the algorithms for -export -- which doesn't matter in your case because you aren't doing -export. (My answer that you linked to was wrong on this point, and one other, and I am fixing.)

Sign up to request clarification or add additional context in comments.

2 Comments

Looks promising. Will approve when I verify it (most probably it will take more time).
Finally I had time to verify this. Adding code which loads both providers resolved my issue. Thanks.
0

Is legacy support enabled in your openssl installation? If not, enable it!

1 Comment

Answer is not on topic! It is not about opessl tools installed on system, but library build by my C++ project. So problem is enabling legacy mode in C++ code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.