This issue tracker
has been migrated to
GitHub
,
and is currently
read-only
.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on
2014-11-24 22:14
by
kroeckx
, last changed
2022-04-11 14:58
by
admin
. This issue is now
closed
.
Files
File name
Uploaded
Description
python2.7-nossl3.patch
kroeckx
,
2014-11-24 22:14
The attached patch makes python work when openssl doesn't have SSLv3 support. It also updates the documentation, which has already improved a lot since my original patch.
The current upstream openssl when compiled with no-ssl2 it defines OPENSSL_NO_SSL2, drops the SSLv2_* method and drops support for SSLv2 in the SSLv23_* methods. When build with no-ssl3 it defines OPENSSL_NO_SSL3 and currently just drops supports for SSLv3 in the SSLv23_method, it does not yet drop the SSLv3_* methods. It's still being argued whether no-ssl3 should drop those symbols or that a new option will be used instead.
So that means that with OPENSSL_NO_SSL3 defined it could be that the SSLv3_* methods still exist and that you can create a socket that only support SSLv3.
I made the SSLv3 methods go away in python if OPENSSL_NO_SSL3 is defined. This at least makes things easier for the test suite so that you know you can test a combination like v3 with v23 or not.
This patch is for 2.7. Please let me know if you need a patch for a different version.
maybe it's time to generalise this one, still found on all branches:
# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
def skip_if_broken_ubuntu_ssl(func):
Clearly we need to support openssl's without SSLv3 so I think some version of this needs to be applied to all branches (preferably in time for 2.7.9, Benjamin?). Kurt, if you haven't already, could you sign the contributor agreement so we can use the patch (https://www.python.org/psf/contrib/contrib-form/)? And I guess it would be nice to generalize the SSLv2 checks as doko suggests.
New changeset 49d267a58cc2 by Benjamin Peterson in branch '2.7':
allow ssl module to compile if openssl doesn't support SSL 3 (closes #22935)
https://hg.python.org/cpython/rev/49d267a58cc2
New changeset 4077e0cd8d48 by Benjamin Peterson in branch '3.4':
allow ssl module to compile if openssl doesn't support SSL 3 (closes #22935)
https://hg.python.org/cpython/rev/4077e0cd8d48
New changeset fbf3747e721c by Benjamin Peterson in branch 'default':
merge 3.4 (#22935)
https://hg.python.org/cpython/rev/fbf3747e721c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/py/dev/34/source/Lib/
ssl.py
", line 122, in <module>
from _ssl import PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
ImportError: cannot import name 'PROTOCOL_SSLv3'
For the default (3.5) branch,
f776771ab0ee
for
Issue21068
changed ssl.py to handle missing SSLv3 support; 3.4 needs something similar.
New changeset 773e55c95703 by Victor Stinner in branch '3.4':
Issue #22935: Fix ssl module when SSLv3 protocol is not supported
https://hg.python.org/cpython/rev/773e55c95703
New changeset fb1ffd40d33e by Victor Stinner in branch 'default':
Issue #22935: Fix test_ssl when the SSLv3 protocol is not supported
https://hg.python.org/cpython/rev/fb1ffd40d33e
New changeset f0297263a1e8 by Victor Stinner in branch '3.4':
Issue #22935: Fix test_ssl when the SSLv3 protocol is not supported
https://hg.python.org/cpython/rev/f0297263a1e8
> The changes for 3.4 are incomplete
Ok, I fixed most obvious issues. There is a major severe issue in Lib/ssl.py:
def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None):
This line fails if PROTOCOL_SSLv3 name does not exist. I propose to use PROTOCOL_SSLv23 by default if PROTOCOL_SSLv3 does not exist, as done in Python 3.5. See attached patch.
A better option (more secure?) is to use PROTOCOL_SSLv23 by default.
What do you think? I prefer to switch to PROTOCOL_SSLv23 by default in Python 3.4.
Oh, in Python 3.4, create_default_context() uses PROTOCOL_SSLv23, SSLSocket, wrap_socket() and _create_unverified_context() use PROTOCOL_SSLv23 by default.
In Python 3.5, get_server_certificate() now uses PROTOCOL_SSLv23 by default because test_ssl failed on the host svn.python.org: see issue #20896.
changeset: 90360:55f62fa5bebc
user: Antoine Pitrou <solipsis@pitrou.net>
date: Wed Apr 16 18:56:28 2014 +0200
files: Doc/library/ssl.rst Lib/ssl.py Lib/test/test_ssl.py Misc/NEWS
description:
Issue #20896: ssl.get_server_certificate() now uses PROTOCOL_SSLv23, not PROTOCOL_SSLv3, for maximum compatibility.
Please always use PROTOCOL_SSLv23 since this is the only forward compatible way of telling OpenSSL to use the best protocol available.
Any of the other options such as PROTOCOL_TLSv1 will fix the protocol version to that one protocol version, whereas PROTOCOL_SSLv23 means to use any protocol starting with SSLv2. In the context options you can then disable SSLv2 and SSLv3 to e.g. have the connection use TLS 1.0 or later.
So this seems to be a function that just gets the certificate? You need to be careful with this since a server could perfectly decide to send a different certificate depending on the client hello it receives. Like if you support ECDSA it might decide to send you the ECDSA certificate instead of the RSA certificate. Or maybe you're even connecting to a different IP address?
In any case, you should always use SSLv23, stop supporting anything else.
> So this seems to be a function that just gets the certificate? You need to be careful with this since a server could perfectly decide to send a different certificate depending on the client hello it receives. (...) In any case, you should always use SSLv23, stop supporting anything else.
I don't understand. You say that depending on the protocol, you may get a different certificate, and then that we should stop supporting multiple protocol. Does it mean that you ask to remove a Python feature?
Even if it is technically possible to return a different certificate, I don't think that much servers will return a different certificate if the client uses SSLv23 instead of SSLv3.
> Any of the other options such as PROTOCOL_TLSv1 will fix the protocol version to that one protocol version, whereas PROTOCOL_SSLv23 means to use any protocol starting with SSLv2. In the context options you can then disable SSLv2 and SSLv3 to e.g. have the connection use TLS 1.0 or later.
get_server_certificate() uses _create_unverified_context() (In Python
2.7, 3.4 & 3.5) which explicitly disable SSLv2 and SSLv3. I still have
trouble to understand which protocol will be negociated. We use SSLv3
and disable SSLv3, so the server can only use SSLv23. Am I right?
https://docs.python.org/dev/library/ssl.html#ssl.wrap_socket
SSLv3 does not support the TLS extensions so it's going to send a totally different Client Hello. It will for instance not indicate with elliptic curves it supports. So yes the behavior for SSLv3 and SSLv23 can be totally different. But even with both SSLv23 and a different cipher list you can get a different certificate.
So what I'm really saying is that if you have an API to get a certificate that creates a new connection and you can set the options for that connection too that you need to document that properly that you might get a different certificate.
> STINNER Victor added the comment:
>> Any of the other options such as PROTOCOL_TLSv1 will fix the protocol version to that one protocol version, whereas PROTOCOL_SSLv23 means to use any protocol starting with SSLv2. In the context options you can then disable SSLv2 and SSLv3 to e.g. have the connection use TLS 1.0 or later.
> get_server_certificate() uses _create_unverified_context() (In Python
> 2.7, 3.4 & 3.5) which explicitly disable SSLv2 and SSLv3. I still have
> trouble to understand which protocol will be negociated. We use SSLv3
> and disable SSLv3, so the server can only use SSLv23. Am I right?
> https://docs.python.org/dev/library/ssl.html#ssl.wrap_socket
I'm not sure what OpenSSL will do if you tell it to use protocol
SSLv3 and then disable this via the options again. This sounds like
it won't connect at all, since PROTOCOL_SSLv3 means: only support
SSLv3 :-)
The logic used for protocol selection in OpenSSL is, well, weird.
You have the choice between fixing one single protocol version or
selecting a range and then disabling certain protocol versions
when configuring the context options.
FWIW: The ssl_version parameter in _create_unverified_context()
already uses the correct default; IMO, exposing the parameter
in get_server_certificate() is fairly useless, unless you want
to (ab)use the function to test supported protocol versions :-)
Setting to release blocker since this needs to be resolved for 3.4.3. FYI, the OS X x86 Tiger 3.4 buildbot has been updated to use a local copy of OpenSSL 1.0.1j with SSLv3 disabled and multiple tests now fail (2.7 and default do not fail, as expected).
http://buildbot.python.org/all/builders/x86%20Tiger%203.4
New changeset a8c4925e2359 by Victor Stinner in branch '3.4':
Issue #20896, #22935: The ssl.get_server_certificate() function now uses the
https://hg.python.org/cpython/rev/a8c4925e2359
Ok, I commited my change to Python 3.4. I'm now waiting for the following buildbot before closing the issue:
http://buildbot.python.org/all/builders/x86%20Tiger%203.4
> I'm now waiting for the following buildbot before closing the issue:
> http://buildbot.python.org/all/builders/x86%20Tiger%203.4
Before my change, test_ssl because with "NameError: name 'PROTOCOL_SSLv3' is not defined". With my change, test_ssl now pass. I close the issue.
Python 2.7, 3.4 and 3.5 all now have the same behaviour.
2022-04-11 14:58:10adminsetgithub: 67124
2015-01-06 15:03:50berker.peksagsetstage: needs patch -> resolved
2015-01-06 12:41:26vstinnersetstatus: open -> closed
resolution: fixed
messages:
+
msg233533
2015-01-06 11:24:59vstinnersetmessages:
+
msg233523
2015-01-06 11:24:05python-devsetmessages:
+
msg233522
2015-01-05 08:51:37vstinnersetmessages:
+
msg233448
2015-01-05 08:49:20ned.deilysetpriority: high -> release blocker
nosy:
+
larry
messages:
+
msg233447
2014-12-12 14:53:07kroeckxsetmessages:
+
msg232552
2014-12-12 14:48:03lemburgsetmessages:
+
msg232551
2014-12-12 13:30:17vstinnersetmessages:
+
msg232548
2014-12-12 13:28:54kroeckxsetmessages:
+
msg232547
2014-12-12 13:23:26vstinnersetmessages:
+
msg232546
2014-12-12 13:16:39vstinnersetmessages:
+
msg232545
2014-12-12 13:08:01kroeckxsetmessages:
+
msg232543
2014-12-12 12:47:55lemburgsetnosy:
+
lemburg
messages:
+
msg232542
2014-12-12 11:56:20vstinnersetfiles:
+
get_server_certificate_sslv23.patch
messages:
+
msg232530
2014-12-12 11:35:39vstinnersetmessages:
+
msg232528
2014-12-12 11:31:40vstinnersetfiles:
+
get_server_certificate_sslv3.patch
messages:
+
msg232527
2014-12-12 11:28:04python-devsetmessages:
+
msg232526
2014-12-12 11:25:49python-devsetmessages:
+
msg232525
2014-12-12 09:44:34ned.deilysetstatus: closed -> open
resolution: fixed -> (no value)
messages:
+
msg232522
stage: resolved -> needs patch
2014-12-08 16:45:28kroeckxsetmessages:
+
msg232315
2014-12-06 08:48:47vstinnersetmessages:
+
msg232238
2014-12-06 03:11:46python-devsetstatus: open -> closed
nosy:
+
python-dev
messages:
+
msg232236
resolution: fixed
stage: patch review -> resolved
2014-12-01 15:54:58kroeckxsetmessages:
+
msg231942
2014-11-30 23:31:22ned.deilysetpriority: normal -> high
nosy:
+
benjamin.peterson
,
ned.deily
messages:
+
msg231911
components:
+ Build
2014-11-28 13:39:53dokosetnosy:
+
doko
messages:
+
msg231815
2014-11-28 13:32:13vstinnersetnosy:
+
vstinner
messages:
+
msg231813
2014-11-24 22:37:25pitrousetstage: patch review
type: compile error
versions:
+ Python 2.7, Python 3.4, Python 3.5
2014-11-24 22:21:37alexsetmessages:
+
msg231627
2014-11-24 22:20:47kroeckxsetmessages:
+
msg231626
2014-11-24 22:15:46alexsetnosy:
+
janssen
,
pitrou
,
giampaolo.rodola
,
christian.heimes
,
alex
,
dstufft
messages:
+
msg231625
2014-11-24 22:14:20kroeckxcreate