wbond / oscrypto

Compiler-free Python crypto library backed by the OS, supporting CPython and PyPy
MIT License
321 stars 71 forks source link

openssl 3.0 - how to enable legacy provider? #60

Closed Leseratte10 closed 2 years ago

Leseratte10 commented 2 years ago

I updated my project to use oscrypto 1.3.0 to support Ubuntu 22.04 with Openssl 3, but I'm running into an issue.

If I'm reading the commit message of 5ae0e79b6239c3bdb024707a2c9ab35d8dfa329d correctly, then oscrypto should support the legacy mode of openssl. However, my application fails when calling parse_pkcs12, and raises an exception in rc2_cbc_pkcs5_decrypt with the message "OpenSSL has been compiled without RC2 support".

Is there anything I can do from within Python / with oscrypto to get around that and have it still use RC2, or can I somehow enable this RC2 support in OpenSSL?

I believe applications do need to actively request this legacy provider, does oscrypto do that?

Looking at this code in _libcrypto.py:

# This enables legacy algorithms in OpenSSL 3.0, such as RC2, etc
# which are used by various tests and some old protocols and things
# like PKCS12
libcrypto_legacy_support = True
if libcrypto_version_info >= (3, ):
    if libcrypto.OSSL_PROVIDER_available(null(), "legacy".encode("ascii")):
        libcrypto.OSSL_PROVIDER_load(null(), "legacy".encode("ascii"))
    else:
        libcrypto_legacy_support = False

this might already be implemented if I'm reading this correctly, but why doesn't it work then? Can I somehow test if Ubuntu 22.04 actually ships completely without this legacy module?

Leseratte10 commented 2 years ago

Okay, just added some debug prints and apparently OSSL_PROVIDER _available(null(), "legacy") is returning False / 0, so the legacy provider might actually be disabled on Ubuntu 22.04 ... damnit.

Leseratte10 commented 2 years ago

Figured out two things:

A) OSSL_PROVIDER_available might be broken on Ubuntu 22.04, as it returns 0 even though the legacy module is actually available.

B) According to OpenSSL documentation, as soon as you load a provider, it will no longer auto-load the default providers, so you'd need to first load the "legacy", then the "default" provider.

Maybe the code can be modded so it doesn't use the "available" function at all and just tries to load the legacy module and sees if it works?

Leseratte10 commented 2 years ago

Sorry for the "comment spam": Looks like OSSL_PROVIDER_available does not indicate whether a provider can loaded, but rather whether it is currently loaded.

So instead of first checking for availability, you need to try and load it immediately, then afterwards check if it's available. I'll be creating a PR.