Skip to content

SSLObject.version returns incorrect value before handshake. #73967

Closed

Description

@Lukasa
mannequin
BPO 29781
Nosy @tiran, @Lukasa
PRs
  • bpo-29781: Fix SSLObject.version before handshake #3364
  • [3.6] bpo-29781: Fix SSLObject.version before handshake (GH-3364) #3381
  • Files
  • test.c
  • 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 = 'https://github.com/tiran'
    closed_at = <Date 2017-09-06.23:39:28.508>
    created_at = <Date 2017-03-10.10:03:04.146>
    labels = ['expert-SSL', 'type-bug']
    title = 'SSLObject.version returns incorrect value before handshake.'
    updated_at = <Date 2017-09-06.23:39:28.507>
    user = 'https://github.com/Lukasa'

    bugs.python.org fields:

    activity = <Date 2017-09-06.23:39:28.507>
    actor = 'christian.heimes'
    assignee = 'christian.heimes'
    closed = True
    closed_date = <Date 2017-09-06.23:39:28.508>
    closer = 'christian.heimes'
    components = ['SSL']
    creation = <Date 2017-03-10.10:03:04.146>
    creator = 'Lukasa'
    dependencies = []
    files = ['46715']
    hgrepos = []
    issue_num = 29781
    keywords = []
    message_count = 7.0
    messages = ['289346', '289348', '289350', '289352', '301384', '301439', '301468']
    nosy_count = 2.0
    nosy_names = ['christian.heimes', 'Lukasa']
    pr_nums = ['3364', '3381']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue29781'
    versions = ['Python 3.5', 'Python 3.6']

    Activity

    1. Lukasa commented on Mar 10, 2017

      Lukasamannequin
      MannequinAuthor

      The SSLObject object from the ssl module has a version() method that is undocumented. A reasonable assumption for the behaviour of that method is that it would follow the behaviour of the same method on SSLSocket(), which has the following documentation:

      Return the actual SSL protocol version negotiated by the connection as
      a string, or None is no secure connection is established. As of this
      writing, possible return values include "SSLv2", "SSLv3", "TLSv1",
      "TLSv1.1" and "TLSv1.2". Recent OpenSSL versions may define more return
      values.

      However, SSLObject does not follow that behaviour:

      Python 3.6.0 (default, Jan 18 2017, 18:08:34) 
      [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import ssl
      >>> ctx = ssl.create_default_context()
      >>> in_bio = ssl.MemoryBIO()
      >>> out_bio = ssl.MemoryBIO()
      >>> buffers = ctx.wrap_bio(in_bio, out_bio)
      >>> buffers.version()
      'TLSv1.2'

      That is, a SSLObject that does not have a TLS session established will incorrectly report that it is using a TLS version. This method should return None in this case.

    2. Lukasa commented on Mar 10, 2017

      Lukasamannequin
      MannequinAuthor

      A quick test reveals that Python 3.5 is also affected.

    3. Lukasa commented on Mar 10, 2017

      Lukasamannequin
      MannequinAuthor

      This actually appears to be an outcome of OpenSSL's logic. I've attached a smallish C file that, when run against OpenSSL 1.0.2 on my machine, prints "TLSv1.2".

      This seems like a behaviour we'll have to work around in Python to get the outcome we want here.

    4. Lukasa commented on Mar 10, 2017

      Lukasamannequin
      MannequinAuthor

      I updated the test script to try with a file-descriptor set and OpenSSL returns TLSv1.2 for that one as well. This strongly suggests that OpenSSL's SSL_get_version documentation is somewhat misleading, and that an SSL object will return a version even when it's not connected.

      If Python wants to consider this a bug, it will need to track connections state for the SSLObject like it does for the SSLSocket. Otherwise, Python can redocument version for SSLObject to say that it will always return a value.

    5. tiran commented on Sep 5, 2017

      @tiran
      Member

      It should be possible to solve the issue w/o tracking the connection state manually. It doesn't work correctly with transparent negotiation -- that is implicit handshake with SSL_write().

      SSL_is_init_finished() (https://www.openssl.org/docs/manmaster/man3/SSL_get_state.html) might be the right function.

    6. tiran commented on Sep 6, 2017

      @tiran
      Member

      New changeset 6877111 by Christian Heimes in branch 'master':
      bpo-29781: Fix SSLObject.version before handshake (bpo-3364)
      6877111

    7. tiran commented on Sep 6, 2017

      @tiran
      Member

      New changeset 6da379b by Christian Heimes in branch '3.6':
      [3.6] bpo-29781: Fix SSLObject.version before handshake (GH-3364) (bpo-3381)
      6da379b

    8. added
      type-bugAn unexpected behavior, bug, or error
      on Sep 6, 2017
    9. 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

    Labels

    topic-SSLtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions