question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Understand OpenSSL 3.0 failures

See original GitHub issue

OpenSSL 3 is supported by Python, we should try running urllib3’s test suite against Python using OpenSSL 3.

Easiest route might be to use Docker in GitHub Actions with Fedora’s “rawhide” image:

Minimum requirements

💵 You can get paid to complete this issue! Please read the docs for more information.

  • Add to the ci GitHub Action in the main branch to test against a platform with access to OpenSSL 3.
  • Create a pytest marker @requires_openssl_lt_3 which adds pytest.mark.xfail to tests when Python is compiled with OpenSSL >= 3.0.0
  • For each failing test on CI figure out why the failure is occurring, document each failure with a comment and add the above pytest marker to the test.
  • Create a GitHub issue which summarizes all the problems that are currently failing tests

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
tirancommented, Jun 9, 2022

No, it’s not a compile-time option. It’s actually more complicated and depends on several things like downstream patches and system-wide settings.

  • With upstream OpenSSL 3.0.x, the call SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) returns 0, which Python maps to TLSVersion.MAXIMUM_SUPPORTED
  • Downstream OpenSSL in Fedora, Ubuntu, and other distros are patched and use custom crypto policies. With Fedora downstream OpenSSL 3.0, the SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) returns the settings based on /etc/crypto-policies/back-ends/opensslcnf.config.

The DEFAULT crypto policy sets TLS 1.2 as minimum and TLS 1.3 as maximum:

$ cat /etc/crypto-policies/back-ends/opensslcnf.config
CipherString = @SECLEVEL=1:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:kRSAPSK:-aDSS:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256
TLS.MinProtocol = TLSv1.2
TLS.MaxProtocol = TLSv1.3
DTLS.MinProtocol = DTLSv1.2
DTLS.MaxProtocol = DTLSv1.2
SignatureAlgorithms = ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:rsa_pss_rsae_sha256:rsa_pss_rsae_sha384:rsa_pss_rsae_sha512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224

You can override the settings by setting OPENSSL_CONF to an invalid path before you load any OpenSSL libraries:

$ python3 -c "import ssl; print(ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT).maximum_version)"
TLSVersion.TLSv1_3
$ OPENSSL_CONF="/invalid" python -c "import ssl; print(ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT).maximum_version)"
TLSVersion.MAXIMUM_SUPPORTED
1reaction
illia-vcommented, Jun 9, 2022

Looks like Ubuntu 22.04 is shipping with Python 3.10 as python3 that has OpenSSL 3.0.2:

#2626 makes tests run on Ubuntu 22.04, tests succeed on Python 3.9–3.11.


I ran tests on Fedora 36 (Python 3.10.4 compiled with OpenSSL 3.0.3) locally too, and found timeouts similar to https://github.com/urllib3/urllib3/issues/2477#issuecomment-966975130 there, but increasing LONG_TIMEOUT to 0.05 fixed them. https://github.com/urllib3/urllib3/blob/9fbab29644bfc8068eb2082d0f25726c91813337/test/__init__.py#L80


Also, three other failures happened in Fedora 36 because the test method assumes that ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT).maximum_version will always be equal to ssl.TLSVersion.MAXIMUM_SUPPORTED.

https://github.com/urllib3/urllib3/blob/622aa69a1f65459232cadf7ff09f9a847d4c89b4/test/with_dummyserver/test_https.py#L947-L950

The assumption is not always true, and it’s actually false for Fedora 36. This is a related code in CPython. And SSL_CTX_ctrl can return different values depending on how OpenSSL has been compiled probably. I do not think this is related to OpenSSL 3.0 specifically.

__________________________________________________________________________________________ TestHTTPS.test_default_ssl_context_ssl_min_max_versions ___________________________________________________________________________________________

self = <test.with_dummyserver.test_https.TestHTTPS object at 0x7f6d8b313880>

    def test_default_ssl_context_ssl_min_max_versions(self) -> None:
        ctx = urllib3.util.ssl_.create_urllib3_context()
        assert ctx.minimum_version == ssl.TLSVersion.TLSv1_2
>       assert ctx.maximum_version == ssl.TLSVersion.MAXIMUM_SUPPORTED
E       AssertionError: assert <TLSVersion.TLSv1_3: 772> == <TLSVersion.MAXIMUM_SUPPORTED: -1>
E        +  where <TLSVersion.TLSv1_3: 772> = <ssl.SSLContext object at 0x7f6d8b00f6c0>.maximum_version
E        +  and   <TLSVersion.MAXIMUM_SUPPORTED: -1> = <enum 'TLSVersion'>.MAXIMUM_SUPPORTED
E        +    where <enum 'TLSVersion'> = ssl.TLSVersion

test/with_dummyserver/test_https.py:950: AssertionError
______________________________________________________________________________________ TestHTTPS_TLSv1_2.test_default_ssl_context_ssl_min_max_versions _______________________________________________________________________________________

self = <test.with_dummyserver.test_https.TestHTTPS_TLSv1_2 object at 0x7f6d8b29c070>

    def test_default_ssl_context_ssl_min_max_versions(self) -> None:
        ctx = urllib3.util.ssl_.create_urllib3_context()
        assert ctx.minimum_version == ssl.TLSVersion.TLSv1_2
>       assert ctx.maximum_version == ssl.TLSVersion.MAXIMUM_SUPPORTED
E       AssertionError: assert <TLSVersion.TLSv1_3: 772> == <TLSVersion.MAXIMUM_SUPPORTED: -1>
E        +  where <TLSVersion.TLSv1_3: 772> = <ssl.SSLContext object at 0x7f6d897e6040>.maximum_version
E        +  and   <TLSVersion.MAXIMUM_SUPPORTED: -1> = <enum 'TLSVersion'>.MAXIMUM_SUPPORTED
E        +    where <enum 'TLSVersion'> = ssl.TLSVersion

test/with_dummyserver/test_https.py:950: AssertionError
______________________________________________________________________________________ TestHTTPS_TLSv1_3.test_default_ssl_context_ssl_min_max_versions _______________________________________________________________________________________

self = <test.with_dummyserver.test_https.TestHTTPS_TLSv1_3 object at 0x7f6d8b2a14e0>

    def test_default_ssl_context_ssl_min_max_versions(self) -> None:
        ctx = urllib3.util.ssl_.create_urllib3_context()
        assert ctx.minimum_version == ssl.TLSVersion.TLSv1_2
>       assert ctx.maximum_version == ssl.TLSVersion.MAXIMUM_SUPPORTED
E       AssertionError: assert <TLSVersion.TLSv1_3: 772> == <TLSVersion.MAXIMUM_SUPPORTED: -1>
E        +  where <TLSVersion.TLSv1_3: 772> = <ssl.SSLContext object at 0x7f6d897e6440>.maximum_version
E        +  and   <TLSVersion.MAXIMUM_SUPPORTED: -1> = <enum 'TLSVersion'>.MAXIMUM_SUPPORTED
E        +    where <enum 'TLSVersion'> = ssl.TLSVersion

test/with_dummyserver/test_https.py:950: AssertionError
Read more comments on GitHub >

github_iconTop Results From Across the Web

New OpenSSL 3.0 vulnerabilities: What you need to ... - GitLab
The OpenSSL Project announced two vulnerabilities found in OpenSSL 3.0-3.0.6 (first released in September 2021).
Read more >
Everything you need to know about the OpenSSL 3.0.7 Patch ...
The vulnerability is a buffer overflow in the X.509 certificate verification, which is the code used to validate TLS certificates. The ...
Read more >
OpenSSL vulnerabilities: Everything you need to know - Wiz
These vulnerabilities affect OpenSSL versions 3.0.0 and above, as well as any application with an embedded impacted OpenSSL library in the ...
Read more >
Qualys Research Alert: OpenSSL 3.0.7 - What You Need To ...
An attacker can craft a malicious email address in a certificate to overflow an arbitrary number of bytes containing the `.' character (decimal ......
Read more >
OpenSSL 3.0 - OpenSSLWiki
These functions are being deprecated in OpenSSL 3.0, and users of these APIs should know that their use can likely bypass provider selection ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found