Author grrrrrrrrr
Recipients christian.heimes, grrrrrrrrr
Date 2017-10-18.13:15:39
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1508332540.28.0.213398074469.issue31809@psf.upfronthosting.co.za>
In-reply-to
Content
When using elliptic curves in combination with the ssl module to wrap a socket, the only curve the client accepts is prime256v1. Expected behavior is to accept all curves that are on the default list and supported by the server.

We noticed the issue when connecting to a server that is configured with a non standard curve, we get

[SSL: WRONG_CURVE] wrong curve (_ssl.c:661)

unless we explicitly specify to use the correct curve for the context using

context.set_ecdh_curve("secp521r1")

The bug happens both when using a context or ssl.wrap_socket directly.



The bug is that cpython calls OpenSSL (or whatever lib is linked) server methods even when the context is purely for client communications. The flow is:

- A ssl.SSLContext gets instantiated that will later be used in SSLContext.wrap_socket with server_side either True or False (bug happens when this is client side, so server_side=False).

- In the context's constructor, where it's not yet clear if the context is for a client or a server socket, there is this code:
https://github.com/python/cpython/blob/b9a860f3bf80b0d4a6c25d0f2f6ef849d9bf3594/Modules/_ssl.c#L2180

That code calls (in many cases, depending on the Python and OpenSSL versions involved) server side only methods, SSL_CTX_set_ecdh_auto or SSL_CTX_set_tmp_ecdh.

Those methods should in theory not influence the client side of the context, there is even a comment in the docs for SSLContext.set_ecdh_curve which does similar things that says "This setting doesn’t apply to client sockets". However, this being OpenSSL, this is not true. The methods actually set the list of acceptable curves that is used for both, server and client side connections, to exactly a single curve, prime256v1. This happens for both, SSL_CTX_set_tmp_ecdh and SSL_CTX_set_ecdh_auto.


Versions affected:

OpenSSL has changed the API twice here. Before 1.0.2, SSL_CTX_set_tmp_ecdh was mandatory, 1.0.2 - <1.1.0 used SSL_CTX_set_ecdh_auto and 1.1.0+ doesn't need this setting at all.

Python 2.7.14+ added a check for 1.1.0+ in https://github.com/python/cpython/commit/f1a696efd6ca674579e25de29ec4053ff5a5ade1 so starting from that version the issue only happens when using OpenSSL <1.1.0. I suspect this is the case for many machines still, including all Macs (haven't confirmed the actual bug there). For LibreSSL the server side methods will be called too, I can't confirm if that combination is vulnerable too.

Python 3.5.3 gives me the same error, no reason to believe that higher versions are not affected.
History
Date User Action Args
2017-10-18 13:15:40grrrrrrrrrsetrecipients: + grrrrrrrrr, christian.heimes
2017-10-18 13:15:40grrrrrrrrrsetmessageid: <1508332540.28.0.213398074469.issue31809@psf.upfronthosting.co.za>
2017-10-18 13:15:40grrrrrrrrrlinkissue31809 messages
2017-10-18 13:15:39grrrrrrrrrcreate