Skip to content

test_min_max_version in test_ssl.py fails when Python is built against LibreSSL; {min,max}imum_version behavior differs from OpenSSL #78176

Closed

Description

@alanhuang122
BPO 33995
Nosy @vstinner, @tiran, @alex, @dstufft, @alanhuang122
PRs
  • bpo-33995: fix ssl tests when built with LibreSSL #8050
  • Superseder
  • bpo-35045: test_min_max_version (test.test_ssl.ContextTests) fails on Fedora 29+ and openssl 1.1.1
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2019-01-18.15:21:55.523>
    created_at = <Date 2018-06-29.05:32:25.722>
    labels = ['3.7', 'expert-SSL', '3.8', 'type-bug', 'tests']
    title = 'test_min_max_version in test_ssl.py fails when Python is built against LibreSSL; {min,max}imum_version behavior differs from OpenSSL'
    updated_at = <Date 2019-01-18.15:21:55.518>
    user = 'https://github.com/alanhuang122'

    bugs.python.org fields:

    activity = <Date 2019-01-18.15:21:55.518>
    actor = 'vstinner'
    assignee = 'docs@python'
    closed = True
    closed_date = <Date 2019-01-18.15:21:55.523>
    closer = 'vstinner'
    components = ['Tests', 'SSL']
    creation = <Date 2018-06-29.05:32:25.722>
    creator = 'Alan.Huang'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 33995
    keywords = ['patch']
    message_count = 3.0
    messages = ['320703', '320890', '333977']
    nosy_count = 7.0
    nosy_names = ['janssen', 'vstinner', 'christian.heimes', 'alex', 'docs@python', 'dstufft', 'Alan.Huang']
    pr_nums = ['8050']
    priority = 'normal'
    resolution = 'duplicate'
    stage = 'resolved'
    status = 'closed'
    superseder = '35045'
    type = 'behavior'
    url = 'https://bugs.python.org/issue33995'
    versions = ['Python 3.7', 'Python 3.8']

    Activity

    1. alanhuang122 commented on Jun 29, 2018

      alanhuang122mannequin
      MannequinAuthor

      LibreSSL's implementation of the function used to get the minimum and maximum SSL versions supported differs from OpenSSL's.

      In short, the issue is in the implementations of SSL_CTX_new - OpenSSL initializes variables ret->{min,max}_proto_version to 0, while LibreSSL initializes corresponding variables to those of the SSL_METHOD given.

      As such, when Python is built with LibreSSL, the default values for an instance of ssl.SSLContext are, in the case of ssl.SSLContext(), ctx.minimum_version = <TLSVersion.TLSv1: 769>; ctx.maximum_version = <TLSVersion.TLSv1_2: 771>.
      This is NOT what test_ssl.py expects; it expects OpenSSL's behavior of initializing the version variables to zero, which _ssl.c then translates to PY_PROTO_{MIN,MAX}IMUM_SUPPORTED -> ssl.TLSVersion.{MIN,MAX}IMUM_SUPPORTED.

      Additionally, LibreSSL, when SSL_CTX_set_{min,max}_proto_version is called with version equal to zero, explicitly sets the minimum / maximum values equal to the minimum / maximum values for the SSL_METHOD it was called with (namely, 769/770/771, in the case of TLS_method()), not the minimum / maximum values supported by the library.

      I have sent an email to the LibreSSL mailing list asking for clarification on this point, namely, if this is intended behavior. If it is, there are two ways that come to mind to work around this behavior. Both ways would only be necessary if IS_LIBRESSL.

      1. Skip test_min_max_version.
      2. Instead of testing that ctx is equal to the extremes after it's been set to one of the extremes, test that it's equal to the actual constants.
        There are two ways this could be accomplished as well:
        a. Use PY_PROTO_{MIN,MAX}IMUM_AVAILABLE, defined in _ssl.c (this may require the addition of another call to PyModule_AddIntConstant to provide access to the constant from ssl). The downside to this approach is that it assumes that TLS_method(), or whatever SSL_METHOD test_ssl.py uses has lower and upper bounds equal to PY_PROTO{MIN,MAX}IMUM_AVAILABLE, which may not always be the case.
        b. Access and store the values for ctx.{min,max}imum_value on creation, then reference them after setting.
        Either of these approaches would likely also have the benefit of removing the need for self.assertIn(ctx.minimum_version, {ssl.TLSVersion.TLSv1_2, ssl.TLSVersion.TLSv1_3}).

      The test that failed was:
      ======================================================================
      FAIL: test_min_max_version (test.test_ssl.ContextTests)
      ----------------------------------------------------------------------

      Traceback (most recent call last):
        File "/home/alan/src/cpython/Lib/test/test_ssl.py", line 1066, in test_min_max_version
          ctx.minimum_version, ssl.TLSVersion.MINIMUM_SUPPORTED
      AssertionError: <TLSVersion.TLSv1: 769> != <TLSVersion.MINIMUM_SUPPORTED: -2>

      Addendum:
      I found the documentation for ssl.TLSVersion.{MAX,MIN}IMUM_SUPPORTED confusing at first - it took me quite a while to realize what the purpose of the constants were; I would have expected them to contain the maximum and minimum protocol versions supported by the library; I see why it was phrased that way, after having boned up on ssl.py, _ssl.c, and OpenSSL/LibreSSL, but think it could could be made clearer.

    2. added
      testsTests in the Lib/test dir
      type-bugAn unexpected behavior, bug, or error
      and removed
      docsDocumentation in the Doc dir
      on Jun 29, 2018
    3. alanhuang122 commented on Jul 2, 2018

      alanhuang122mannequin
      MannequinAuthor

      PR 8050 implements option 2a (use PY_PROTO_{MIN,MAX}IMUM_AVAILABLE).

    4. vstinner commented on Jan 18, 2019

      @vstinner
      Member

      Oh, this issue looks like bpo-35045 which has been fixed.

    5. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.7 (EOL)end of life3.8 (EOL)end of lifetestsTests in the Lib/test dirtopic-SSLtype-bugAn unexpected behavior, bug, or error

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions