Another deprecation: I like to deprecate all arguments from SSLSocket.__init__() and require users to go through SSLContext.wrap_socket(). It's going to make the implementation much simpler. The argument list is just crazy:
I have deprecated cafile, capath and cadefault for urlopen(). The function didn't pop up on my radar because I was looking for certfile and cert_file, not cafile. I also added deprecations to the documentation of SSLSocket.read and write.
The performance benefit is not worth the risk. For 10 httplib requests to pypi.python.org, a shared SSLContext is about 5% faster than a new context for each request. Session resumption improves the simple test case by another 20%.
Leaving the option of context caching entirely to the caller would definitely make things simpler - my main interest is just in avoiding a hard compatibility break for folks that aren't doing anything particularly wrong, by which I mean specifically cases where a wrap_socket() implementation like this one would continue to work for them:
Traceback (most recent call last):
File "/media/disk/home/proj/python/cpython/Lib/test/test_httplib.py", line 1646, in test_local_bad_hostname
check_hostname=True)
File "/media/disk/home/proj/python/cpython/Lib/http/client.py", line 1373, in __init__DeprecationWarning, 2)
DeprecationWarning: key_file, cert_file and check_hostname are deprecated, use a custom context instead.
Traceback (most recent call last):
File "/home/serhiy/py/cpython-debug/Lib/test/test_imaplib.py", line 641, in test_logincapa_with_client_certfile
_server =self.imap_class(self.host, self.port, certfile=CERTFILE)
File "/home/serhiy/py/cpython-debug/Lib/imaplib.py", line 1273, in __init__"custom ssl_context instead", DeprecationWarning, 2)
DeprecationWarning: keyfile and certfile are deprecated, use acustom ssl_context instead
which is indeed unverified: despite defaulting to PROTOCOL_TLS_CLIENT, which "enables CERT_REQUIRED and check_hostname by default.", it overrides that by setting check_hostname=False:
I don't have a cert for 46.23.90.174 (no one will give out certs for IPs!), so this is wrong!
In order to actually enable verification you need to know the incantation. It's not that long but it is subtle and frighteningly easy to get wrong. Here it is:
I can see from this thread there were some concerns about breaking people's self-signed certs back in 2016. But it's five years later now and letsencrypt is super common now, and most servers and clients are enforcing TLS, especially when credentials are involved.
Could this be revisited?
Thanks for any attention you have gifted to this :)
The part with "make ftplib, imaplib, nntplib, pop3lib, smtplib etc. validate certs by default" was not implemented. These modules still default to unverified connections.
Activity
tiran commented on Sep 8, 2016
I like to deprecate some SSL related parts of Python:
Lukasa commented on Sep 8, 2016
10/10, yes. I will happily provide code review for this.
vstinner commented on Sep 8, 2016
I'm not sure about this one:
http://legacy.python.org/dev/peps/pep-0476/#other-protocols
tiran commented on Sep 8, 2016
Another deprecation: I like to deprecate all arguments from SSLSocket.__init__() and require users to go through SSLContext.wrap_socket(). It's going to make the implementation much simpler. The argument list is just crazy:
vstinner commented on Sep 8, 2016
I like the idea of using SSLContext as the obvious and only choice to
"configure" SSL.
tiran commented on Sep 8, 2016
memo to me: check if SSLContext.wrap_socket() can deal with a fileno as sock argument.
tiran commented on Sep 8, 2016
First draft of a patch: https://github.com/tiran/cpython/commits/feature/ssl_deprecation
vadmium commented on Sep 9, 2016
urllib.request.urlopen() should be affected too right?
orsenthil commented on Sep 9, 2016
Yes, urllib.request.urlopen needs an update too. It takes those certfile and keyfile and usage of those could be deprecated in favor of context.
tiran commented on Sep 9, 2016
I have deprecated cafile, capath and cadefault for urlopen(). The function didn't pop up on my radar because I was looking for certfile and cert_file, not cafile. I also added deprecations to the documentation of SSLSocket.read and write.
10 remaining items
tiran commented on Sep 11, 2016
The performance benefit is not worth the risk. For 10 httplib requests to pypi.python.org, a shared SSLContext is about 5% faster than a new context for each request. Session resumption improves the simple test case by another 20%.
ncoghlan commented on Sep 11, 2016
Leaving the option of context caching entirely to the caller would definitely make things simpler - my main interest is just in avoiding a hard compatibility break for folks that aren't doing anything particularly wrong, by which I mean specifically cases where a wrap_socket() implementation like this one would continue to work for them:
vadmium commented on Sep 11, 2016
New test failure when using -Werror:
======================================================================
ERROR: test_local_bad_hostname (test.test_httplib.HTTPSTest)
----------------------------------------------------------------------
python-dev commented on Sep 11, 2016
New changeset 2e541e994927 by Christian Heimes in branch 'default':
bpo-28022: Catch deprecation warning in test_httplib, reported by Martin Panter
https://hg.python.org/cpython/rev/2e541e994927
tiran commented on Sep 11, 2016
Thanks for the report. "./python -Werror -m test -uall test_httplib" is now passing for me.
serhiy-storchaka commented on Sep 11, 2016
test_imaplib is failed too.
======================================================================
ERROR: test_logincapa_with_client_certfile (test.test_imaplib.RemoteIMAP_SSLTest)
----------------------------------------------------------------------
python-dev commented on Sep 11, 2016
New changeset 57e88d1159fc by Christian Heimes in branch 'default':
Issue bpo-28022: Catch another deprecation warning in imaplib
https://hg.python.org/cpython/rev/57e88d1159fc
serhiy-storchaka commented on Oct 22, 2017
Shouldn't this issue be closed?
Since SSL context arguments are not supported in 2.7, the deprecated arguments can't be removed until EOL of 2.7.
kousu commented on Aug 8, 2021
Hello everyone, and thank you as usual for all your hard work keeping the python ecosystem going.
I saw that the start of this thread said it was going to
but this hasn't been done, at least not for imaplib. imaplib is still calling the undocumented "ssl._create_stdlib_context":
cpython/Lib/imaplib.py
Line 1320 in 2b496e7
which is actually "ssl._create_unverified_context":
cpython/Lib/ssl.py
Line 842 in 2b496e7
which is indeed unverified: despite defaulting to PROTOCOL_TLS_CLIENT, which "enables CERT_REQUIRED and check_hostname by default.", it overrides that by setting check_hostname=False:
cpython/Lib/ssl.py
Line 811 in 2b496e7
To demonstrate, check out this tester script:
I don't have a cert for 46.23.90.174 (no one will give out certs for IPs!), so this is wrong!
In order to actually enable verification you need to know the incantation. It's not that long but it is subtle and frighteningly easy to get wrong. Here it is:
I can see from this thread there were some concerns about breaking people's self-signed certs back in 2016. But it's five years later now and letsencrypt is super common now, and most servers and clients are enforcing TLS, especially when credentials are involved.
Could this be revisited?
Thanks for any attention you have gifted to this :)
tiran commented on Aug 8, 2021
The part with "make ftplib, imaplib, nntplib, pop3lib, smtplib etc. validate certs by default" was not implemented. These modules still default to unverified connections.