Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 562358 Details for
Bug 673960
dev-lang/python-3.4.10: removal / with dev-libs/openssl-1.1.0j - Modules/_ssl.c:694:35: error: dereferencing pointer to incomplete type 'X509_NAME_ENTRY' {aka 'struct X509_name_entry_st'}
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Support for OpenSSL 1.1 backported from Python 3.5
fix-openssl-1.1.patch (text/plain), 50.05 KB, created by
Aliaksei Urbanski
on 2019-01-21 03:47:38 UTC
(
hide
)
Description:
Support for OpenSSL 1.1 backported from Python 3.5
Filename:
MIME Type:
Creator:
Aliaksei Urbanski
Created:
2019-01-21 03:47:38 UTC
Size:
50.05 KB
patch
obsolete
>diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst >index 1ad4d61806..7a5ce96774 100644 >--- a/Doc/library/ssl.rst >+++ b/Doc/library/ssl.rst >@@ -179,7 +179,7 @@ instead. > use. Typically, the server chooses a particular protocol version, and the > client must adapt to the server's choice. Most of the versions are not > interoperable with the other versions. If not specified, the default is >- :data:`PROTOCOL_SSLv23`; it provides the most compatibility with other >+ :data:`PROTOCOL_TLS`; it provides the most compatibility with other > versions. > > Here's a table showing which versions in a client (down the side) can connect >@@ -188,11 +188,11 @@ instead. > .. table:: > > ======================== ========= ========= ========== ========= =========== =========== >- *client* / **server** **SSLv2** **SSLv3** **SSLv23** **TLSv1** **TLSv1.1** **TLSv1.2** >+ *client* / **server** **SSLv2** **SSLv3** **TLS** **TLSv1** **TLSv1.1** **TLSv1.2** > ------------------------ --------- --------- ---------- --------- ----------- ----------- > *SSLv2* yes no yes no no no > *SSLv3* no yes yes no no no >- *SSLv23* no yes yes yes yes yes >+ *TLS* (*SSLv23*) no yes yes yes yes yes > *TLSv1* no no yes yes no no > *TLSv1.1* no no yes no yes no > *TLSv1.2* no no yes no no yes >@@ -245,7 +245,7 @@ purposes. > :const:`None`, this function can choose to trust the system's default > CA certificates instead. > >- The settings are: :data:`PROTOCOL_SSLv23`, :data:`OP_NO_SSLv2`, and >+ The settings are: :data:`PROTOCOL_TLS`, :data:`OP_NO_SSLv2`, and > :data:`OP_NO_SSLv3` with high encryption cipher suites without RC4 and > without unauthenticated cipher suites. Passing :data:`~Purpose.SERVER_AUTH` > as *purpose* sets :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED` >@@ -323,6 +323,11 @@ Random generation > > .. versionadded:: 3.3 > >+ .. deprecated:: 3.5.3 >+ >+ OpenSSL has deprecated :func:`ssl.RAND_pseudo_bytes`, use >+ :func:`ssl.RAND_bytes` instead. >+ > .. function:: RAND_status() > > Return ``True`` if the SSL pseudo-random number generator has been seeded >@@ -341,6 +346,8 @@ Random generation > See http://egd.sourceforge.net/ or http://prngd.sourceforge.net/ for sources > of entropy-gathering daemons. > >+ Availability: not available with LibreSSL and OpenSSL > 1.1.0 >+ > .. function:: RAND_add(bytes, entropy) > > Mix the given *bytes* into the SSL pseudo-random number generator. The >@@ -396,7 +403,7 @@ Certificate handling > >>> time.ctime(ssl.cert_time_to_seconds("May 9 00:00:00 2007 GMT")) > 'Wed May 9 00:00:00 2007' > >-.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None) >+.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None) > > Given the address ``addr`` of an SSL-protected server, as a (*hostname*, > *port-number*) pair, fetches the server's certificate, and returns it as a >@@ -410,6 +417,10 @@ Certificate handling > .. versionchanged:: 3.3 > This function is now IPv6-compatible. > >+ .. versionchanged:: 3.5 (backported) >+ The default *ssl_version* is changed from :data:`PROTOCOL_SSLv3` to >+ :data:`PROTOCOL_TLS` for maximum compatibility with modern servers. >+ > .. function:: DER_cert_to_PEM_cert(DER_cert_bytes) > > Given a certificate as a DER-encoded blob of bytes, returns a PEM-encoded >@@ -434,6 +445,9 @@ Certificate handling > * :attr:`openssl_capath_env` - OpenSSL's environment key that points to a capath, > * :attr:`openssl_capath` - hard coded path to a capath directory > >+ Availability: LibreSSL ignores the environment vars >+ :attr:`openssl_cafile_env` and :attr:`openssl_capath_env` >+ > .. versionadded:: 3.4 > > .. function:: enum_certificates(store_name) >@@ -551,11 +565,21 @@ Constants > > .. versionadded:: 3.4.4 > >-.. data:: PROTOCOL_SSLv23 >+.. data:: PROTOCOL_TLS > > Selects the highest protocol version that both the client and server support. > Despite the name, this option can select "TLS" protocols as well as "SSL". > >+ .. versionadded:: 3.5.3 (backported) >+ >+.. data:: PROTOCOL_SSLv23 >+ >+ Alias for data:`PROTOCOL_TLS`. >+ >+ .. deprecated:: 3.5.3 >+ >+ Use data:`PROTOCOL_TLS` instead. >+ > .. data:: PROTOCOL_SSLv2 > > Selects SSL version 2 as the channel encryption protocol. >@@ -567,6 +591,10 @@ Constants > > SSL version 2 is insecure. Its use is highly discouraged. > >+ .. deprecated:: 3.5.3 >+ >+ OpenSSL has removed support for SSLv2. >+ > .. data:: PROTOCOL_SSLv3 > > Selects SSL version 3 as the channel encryption protocol. >@@ -578,10 +606,20 @@ Constants > > SSL version 3 is insecure. Its use is highly discouraged. > >+ .. deprecated:: 3.5.3 >+ >+ OpenSSL has deprecated all version specific protocols. Use the default >+ protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead. >+ > .. data:: PROTOCOL_TLSv1 > > Selects TLS version 1.0 as the channel encryption protocol. > >+ .. deprecated:: 3.5.3 >+ >+ OpenSSL has deprecated all version specific protocols. Use the default >+ protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead. >+ > .. data:: PROTOCOL_TLSv1_1 > > Selects TLS version 1.1 as the channel encryption protocol. >@@ -589,6 +627,11 @@ Constants > > .. versionadded:: 3.4 > >+ .. deprecated:: 3.5.3 >+ >+ OpenSSL has deprecated all version specific protocols. Use the default >+ protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead. >+ > .. data:: PROTOCOL_TLSv1_2 > > Selects TLS version 1.2 as the channel encryption protocol. This is the >@@ -597,6 +640,11 @@ Constants > > .. versionadded:: 3.4 > >+ .. deprecated:: 3.5.3 >+ >+ OpenSSL has deprecated all version specific protocols. Use the default >+ protocol data:`PROTOCOL_TLS` with flags like data:`OP_NO_SSLv3` instead. >+ > .. data:: OP_ALL > > Enables workarounds for various bugs present in other SSL implementations. >@@ -608,23 +656,32 @@ Constants > .. data:: OP_NO_SSLv2 > > Prevents an SSLv2 connection. This option is only applicable in >- conjunction with :const:`PROTOCOL_SSLv23`. It prevents the peers from >+ conjunction with :const:`PROTOCOL_TLS`. It prevents the peers from > choosing SSLv2 as the protocol version. > > .. versionadded:: 3.2 > >+ .. deprecated:: 3.5.3 >+ >+ SSLv2 is deprecated >+ >+ > .. data:: OP_NO_SSLv3 > > Prevents an SSLv3 connection. This option is only applicable in >- conjunction with :const:`PROTOCOL_SSLv23`. It prevents the peers from >+ conjunction with :const:`PROTOCOL_TLS`. It prevents the peers from > choosing SSLv3 as the protocol version. > > .. versionadded:: 3.2 > >+ .. deprecated:: 3.5.3 >+ >+ SSLv3 is deprecated >+ > .. data:: OP_NO_TLSv1 > > Prevents a TLSv1 connection. This option is only applicable in >- conjunction with :const:`PROTOCOL_SSLv23`. It prevents the peers from >+ conjunction with :const:`PROTOCOL_TLS`. It prevents the peers from > choosing TLSv1 as the protocol version. > > .. versionadded:: 3.2 >@@ -632,7 +689,7 @@ Constants > .. data:: OP_NO_TLSv1_1 > > Prevents a TLSv1.1 connection. This option is only applicable in conjunction >- with :const:`PROTOCOL_SSLv23`. It prevents the peers from choosing TLSv1.1 as >+ with :const:`PROTOCOL_TLS`. It prevents the peers from choosing TLSv1.1 as > the protocol version. Available only with openssl version 1.0.1+. > > .. versionadded:: 3.4 >@@ -640,7 +697,7 @@ Constants > .. data:: OP_NO_TLSv1_2 > > Prevents a TLSv1.2 connection. This option is only applicable in conjunction >- with :const:`PROTOCOL_SSLv23`. It prevents the peers from choosing TLSv1.2 as >+ with :const:`PROTOCOL_TLS`. It prevents the peers from choosing TLSv1.2 as > the protocol version. Available only with openssl version 1.0.1+. > > .. versionadded:: 3.4 >@@ -1002,17 +1059,21 @@ such as SSL configuration options, certificate(s) and private key(s). > It also manages a cache of SSL sessions for server-side sockets, in order > to speed up repeated connections from the same clients. > >-.. class:: SSLContext(protocol) >+.. class:: SSLContext(protocol=PROTOCOL_TLS) > >- Create a new SSL context. You must pass *protocol* which must be one >+ Create a new SSL context. You may pass *protocol* which must be one > of the ``PROTOCOL_*`` constants defined in this module. >- :data:`PROTOCOL_SSLv23` is currently recommended for maximum >- interoperability. >+ :data:`PROTOCOL_TLS` is currently recommended for maximum >+ interoperability and default value. > > .. seealso:: > :func:`create_default_context` lets the :mod:`ssl` module choose > security settings for a given purpose. > >+ .. versionchanged:: 3.5.3 (backported) >+ >+ :data:`PROTOCOL_TLS` is the default value. >+ > > :class:`SSLContext` objects have the following methods and attributes: > >@@ -1495,7 +1556,7 @@ If you prefer to tune security settings yourself, you might create > a context from scratch (but beware that you might not get the settings > right):: > >- >>> context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) >+ >>> context = ssl.SSLContext(ssl.PROTOCOL_TLS) > >>> context.verify_mode = ssl.CERT_REQUIRED > >>> context.check_hostname = True > >>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt") >@@ -1760,15 +1821,17 @@ Protocol versions > > SSL versions 2 and 3 are considered insecure and are therefore dangerous to > use. If you want maximum compatibility between clients and servers, it is >-recommended to use :const:`PROTOCOL_SSLv23` as the protocol version and then >+recommended to use :const:`PROTOCOL_TLS` as the protocol version and then > disable SSLv2 and SSLv3 explicitly using the :data:`SSLContext.options` > attribute:: > >- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) >+ context = ssl.SSLContext(ssl.PROTOCOL_TLS) > context.options |= ssl.OP_NO_SSLv2 > context.options |= ssl.OP_NO_SSLv3 >+ context.options |= ssl.OP_NO_TLSv1 >+ context.options |= ssl.OP_NO_TLSv1_1 > >-The SSL context created above will only allow TLSv1 and later (if >+The SSL context created above will only allow TLSv1.2 and later (if > supported by your system) connections. > > Cipher selection >diff --git a/Lib/ssl.py b/Lib/ssl.py >index 873aa4798b..c1aaec74ec 100644 >--- a/Lib/ssl.py >+++ b/Lib/ssl.py >@@ -51,6 +51,7 @@ The following constants identify various SSL protocol variants: > PROTOCOL_SSLv2 > PROTOCOL_SSLv3 > PROTOCOL_SSLv23 >+PROTOCOL_TLS > PROTOCOL_TLSv1 > PROTOCOL_TLSv1_1 > PROTOCOL_TLSv1_2 >@@ -92,7 +93,7 @@ import re > import sys > import os > from collections import namedtuple >-from enum import Enum as _Enum >+from enum import Enum as _Enum, IntEnum as _IntEnum > > import _ssl # if we can't import it, let the error propagate > >@@ -126,23 +127,18 @@ from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN > > from _ssl import _OPENSSL_API_VERSION > >+_IntEnum._convert( >+ '_SSLMethod', __name__, >+ lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23', >+ source=_ssl) >+ >+PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS >+_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()} > >-_PROTOCOL_NAMES = {value: name for name, value in globals().items() if name.startswith('PROTOCOL_')} > try: >- from _ssl import PROTOCOL_SSLv2 > _SSLv2_IF_EXISTS = PROTOCOL_SSLv2 >-except ImportError: >+except NameError: > _SSLv2_IF_EXISTS = None >-else: >- _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2" >- >-try: >- from _ssl import PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2 >-except ImportError: >- pass >-else: >- _PROTOCOL_NAMES[PROTOCOL_TLSv1_1] = "TLSv1.1" >- _PROTOCOL_NAMES[PROTOCOL_TLSv1_2] = "TLSv1.2" > > if sys.platform == "win32": > from _ssl import enum_certificates, enum_crls >@@ -348,13 +344,13 @@ class SSLContext(_SSLContext): > __slots__ = ('protocol', '__weakref__') > _windows_cert_stores = ("CA", "ROOT") > >- def __new__(cls, protocol, *args, **kwargs): >+ def __new__(cls, protocol=PROTOCOL_TLS, *args, **kwargs): > self = _SSLContext.__new__(cls, protocol) > if protocol != _SSLv2_IF_EXISTS: > self.set_ciphers(_DEFAULT_CIPHERS) > return self > >- def __init__(self, protocol): >+ def __init__(self, protocol=PROTOCOL_TLS): > self.protocol = protocol > > def wrap_socket(self, sock, server_side=False, >@@ -408,7 +404,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, > if not isinstance(purpose, _ASN1Object): > raise TypeError(purpose) > >- context = SSLContext(PROTOCOL_SSLv23) >+ context = SSLContext(PROTOCOL_TLS) > > # SSLv2 considered harmful. > context.options |= OP_NO_SSLv2 >@@ -445,7 +441,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, > context.load_default_certs(purpose) > return context > >-def _create_unverified_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None, >+def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=None, > check_hostname=False, purpose=Purpose.SERVER_AUTH, > certfile=None, keyfile=None, > cafile=None, capath=None, cadata=None): >@@ -501,7 +497,7 @@ class SSLSocket(socket): > > def __init__(self, sock=None, keyfile=None, certfile=None, > server_side=False, cert_reqs=CERT_NONE, >- ssl_version=PROTOCOL_SSLv23, ca_certs=None, >+ ssl_version=PROTOCOL_TLS, ca_certs=None, > do_handshake_on_connect=True, > family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None, > suppress_ragged_eofs=True, npn_protocols=None, ciphers=None, >@@ -883,7 +879,7 @@ class SSLSocket(socket): > > def wrap_socket(sock, keyfile=None, certfile=None, > server_side=False, cert_reqs=CERT_NONE, >- ssl_version=PROTOCOL_SSLv23, ca_certs=None, >+ ssl_version=PROTOCOL_TLS, ca_certs=None, > do_handshake_on_connect=True, > suppress_ragged_eofs=True, > ciphers=None): >@@ -930,7 +926,7 @@ def PEM_cert_to_DER_cert(pem_cert_string): > d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)] > return base64.decodebytes(d.encode('ASCII', 'strict')) > >-def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None): >+def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None): > """Retrieve the certificate from the server at the specified address, > and return it as a PEM-encoded string. > If 'ca_certs' is specified, validate the server cert against it. >diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py >index 19ef354a65..9cd0910923 100644 >--- a/Lib/test/test_ssl.py >+++ b/Lib/test/test_ssl.py >@@ -23,6 +23,9 @@ ssl = support.import_module("ssl") > > PROTOCOLS = sorted(ssl._PROTOCOL_NAMES) > HOST = support.HOST >+IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL') >+IS_OPENSSL_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0) >+ > > def data_file(*name): > return os.path.join(os.path.dirname(__file__), *name) >@@ -134,6 +137,14 @@ class BasicSocketTests(unittest.TestCase): > self.assertIn(ssl.HAS_SNI, {True, False}) > self.assertIn(ssl.HAS_ECDH, {True, False}) > >+ def test_str_for_enums(self): >+ # Make sure that the PROTOCOL_* constants have enum-like string >+ # reprs. >+ proto = ssl.PROTOCOL_TLS >+ self.assertEqual(str(proto), '_SSLMethod.PROTOCOL_TLS') >+ ctx = ssl.SSLContext(proto) >+ self.assertIs(ctx.protocol, proto) >+ > def test_random(self): > v = ssl.RAND_status() > if support.verbose: >@@ -296,9 +307,9 @@ class BasicSocketTests(unittest.TestCase): > self.assertGreaterEqual(status, 0) > self.assertLessEqual(status, 15) > # Version string as returned by {Open,Libre}SSL, the format might change >- if "LibreSSL" in s: >- self.assertTrue(s.startswith("LibreSSL {:d}.{:d}".format(major, minor)), >- (s, t)) >+ if IS_LIBRESSL: >+ self.assertTrue(s.startswith("LibreSSL {:d}".format(major)), >+ (s, t, hex(n))) > else: > self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)), > (s, t)) >@@ -655,7 +666,8 @@ class ContextTests(unittest.TestCase): > def test_constructor(self): > for protocol in PROTOCOLS: > ssl.SSLContext(protocol) >- self.assertRaises(TypeError, ssl.SSLContext) >+ ctx = ssl.SSLContext() >+ self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLS) > self.assertRaises(ValueError, ssl.SSLContext, -1) > self.assertRaises(ValueError, ssl.SSLContext, 42) > >@@ -676,15 +688,15 @@ class ContextTests(unittest.TestCase): > def test_options(self): > ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) > # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value >- self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, >- ctx.options) >+ default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3) >+ if not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0): >+ default |= ssl.OP_NO_COMPRESSION >+ self.assertEqual(default, ctx.options) > ctx.options |= ssl.OP_NO_TLSv1 >- self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1, >- ctx.options) >+ self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options) > if can_clear_options(): >- ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1 >- self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3, >- ctx.options) >+ ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1) >+ self.assertEqual(default, ctx.options) > ctx.options = 0 > # Ubuntu has OP_NO_SSLv3 forced on by default > self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3) >@@ -1020,6 +1032,7 @@ class ContextTests(unittest.TestCase): > self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH') > > @unittest.skipIf(sys.platform == "win32", "not-Windows specific") >+ @unittest.skipIf(IS_LIBRESSL, "LibreSSL doesn't support env vars") > def test_load_default_certs_env(self): > ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) > with support.EnvironmentVarGuard() as env: >@@ -1505,6 +1518,94 @@ class NetworkedTests(unittest.TestCase): > self.assertIs(ss.context, ctx2) > self.assertIs(ss._sslobj.context, ctx2) > >+ >+class NetworkedBIOTests(unittest.TestCase): >+ >+ def ssl_io_loop(self, sock, incoming, outgoing, func, *args, **kwargs): >+ # A simple IO loop. Call func(*args) depending on the error we get >+ # (WANT_READ or WANT_WRITE) move data between the socket and the BIOs. >+ timeout = kwargs.get('timeout', 10) >+ count = 0 >+ while True: >+ errno = None >+ count += 1 >+ try: >+ ret = func(*args) >+ except ssl.SSLError as e: >+ if e.errno not in (ssl.SSL_ERROR_WANT_READ, >+ ssl.SSL_ERROR_WANT_WRITE): >+ raise >+ errno = e.errno >+ # Get any data from the outgoing BIO irrespective of any error, and >+ # send it to the socket. >+ buf = outgoing.read() >+ sock.sendall(buf) >+ # If there's no error, we're done. For WANT_READ, we need to get >+ # data from the socket and put it in the incoming BIO. >+ if errno is None: >+ break >+ elif errno == ssl.SSL_ERROR_WANT_READ: >+ buf = sock.recv(32768) >+ if buf: >+ incoming.write(buf) >+ else: >+ incoming.write_eof() >+ if support.verbose: >+ sys.stdout.write("Needed %d calls to complete %s().\n" >+ % (count, func.__name__)) >+ return ret >+ >+ def test_handshake(self): >+ with support.transient_internet(REMOTE_HOST): >+ sock = socket.socket(socket.AF_INET) >+ sock.connect((REMOTE_HOST, 443)) >+ incoming = ssl.MemoryBIO() >+ outgoing = ssl.MemoryBIO() >+ ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) >+ ctx.verify_mode = ssl.CERT_REQUIRED >+ ctx.load_verify_locations(REMOTE_ROOT_CERT) >+ ctx.check_hostname = True >+ sslobj = ctx.wrap_bio(incoming, outgoing, False, REMOTE_HOST) >+ self.assertIs(sslobj._sslobj.owner, sslobj) >+ self.assertIsNone(sslobj.cipher()) >+ self.assertIsNotNone(sslobj.shared_ciphers()) >+ self.assertRaises(ValueError, sslobj.getpeercert) >+ if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES: >+ self.assertIsNone(sslobj.get_channel_binding('tls-unique')) >+ self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake) >+ self.assertTrue(sslobj.cipher()) >+ self.assertIsNotNone(sslobj.shared_ciphers()) >+ self.assertTrue(sslobj.getpeercert()) >+ if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES: >+ self.assertTrue(sslobj.get_channel_binding('tls-unique')) >+ try: >+ self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap) >+ except ssl.SSLSyscallError: >+ # self-signed.pythontest.net probably shuts down the TCP >+ # connection without sending a secure shutdown message, and >+ # this is reported as SSL_ERROR_SYSCALL >+ pass >+ self.assertRaises(ssl.SSLError, sslobj.write, b'foo') >+ sock.close() >+ >+ def test_read_write_data(self): >+ with support.transient_internet(REMOTE_HOST): >+ sock = socket.socket(socket.AF_INET) >+ sock.connect((REMOTE_HOST, 443)) >+ incoming = ssl.MemoryBIO() >+ outgoing = ssl.MemoryBIO() >+ ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) >+ ctx.verify_mode = ssl.CERT_NONE >+ sslobj = ctx.wrap_bio(incoming, outgoing, False) >+ self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake) >+ req = b'GET / HTTP/1.0\r\n\r\n' >+ self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req) >+ buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024) >+ self.assertEqual(buf[:5], b'HTTP/') >+ self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap) >+ sock.close() >+ >+ > try: > import threading > except ImportError: >@@ -2629,6 +2730,21 @@ else: > s.connect((HOST, server.port)) > self.assertIn("no shared cipher", str(server.conn_errors[0])) > >+ def test_version_basic(self): >+ """ >+ Basic tests for SSLSocket.version(). >+ More tests are done in the test_protocol_*() methods. >+ """ >+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) >+ with ThreadedEchoServer(CERTFILE, >+ ssl_version=ssl.PROTOCOL_TLSv1, >+ chatty=False) as server: >+ with context.wrap_socket(socket.socket()) as s: >+ self.assertIs(s.version(), None) >+ s.connect((HOST, server.port)) >+ self.assertEqual(s.version(), 'TLSv1') >+ self.assertIs(s.version(), None) >+ > @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL") > def test_default_ecdh_curve(self): > # Issue #21015: elliptic curve-based Diffie Hellman key exchange >@@ -2878,6 +2994,30 @@ else: > self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR') > self.assertIn("TypeError", stderr.getvalue()) > >+ def test_shared_ciphers(self): >+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) >+ server_context.load_cert_chain(SIGNED_CERTFILE) >+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) >+ client_context.verify_mode = ssl.CERT_REQUIRED >+ client_context.load_verify_locations(SIGNING_CA) >+ if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2): >+ client_context.set_ciphers("AES128:AES256") >+ server_context.set_ciphers("AES256") >+ alg1 = "AES256" >+ alg2 = "AES-256" >+ else: >+ client_context.set_ciphers("AES:3DES") >+ server_context.set_ciphers("3DES") >+ alg1 = "3DES" >+ alg2 = "DES-CBC3" >+ >+ stats = server_params_test(client_context, server_context) >+ ciphers = stats['server_shared_ciphers'][0] >+ self.assertGreater(len(ciphers), 0) >+ for name, tls_version, bits in ciphers: >+ if not alg1 in name.split("-") and alg2 not in name: >+ self.fail(name) >+ > def test_read_write_after_close_raises_valuerror(self): > context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) > context.verify_mode = ssl.CERT_REQUIRED >diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c >index 5b0a7be12b..1f353e4bd8 100644 >--- a/Modules/_hashopenssl.c >+++ b/Modules/_hashopenssl.c >@@ -20,7 +20,6 @@ > > /* EVP is the preferred interface to hashing in OpenSSL */ > #include <openssl/evp.h> >-#include <openssl/hmac.h> > /* We use the object interface to discover what hashes OpenSSL supports. */ > #include <openssl/objects.h> > #include "openssl/err.h" >@@ -31,15 +30,21 @@ > #define HASH_OBJ_CONSTRUCTOR 0 > #endif > >-/* Minimum OpenSSL version needed to support sha224 and higher. */ >-#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x00908000) >-#define _OPENSSL_SUPPORTS_SHA2 >+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) >+/* OpenSSL < 1.1.0 */ >+#define EVP_MD_CTX_new EVP_MD_CTX_create >+#define EVP_MD_CTX_free EVP_MD_CTX_destroy >+#define HAS_FAST_PKCS5_PBKDF2_HMAC 0 >+#include <openssl/hmac.h> >+#else >+/* OpenSSL >= 1.1.0 */ >+#define HAS_FAST_PKCS5_PBKDF2_HMAC 1 > #endif > > typedef struct { > PyObject_HEAD > PyObject *name; /* name of this hash algorithm */ >- EVP_MD_CTX ctx; /* OpenSSL message digest context */ >+ EVP_MD_CTX *ctx; /* OpenSSL message digest context */ > #ifdef WITH_THREAD > PyThread_type_lock lock; /* OpenSSL context lock */ > #endif >@@ -51,7 +56,6 @@ static PyTypeObject EVPtype; > > #define DEFINE_CONSTS_FOR_NEW(Name) \ > static PyObject *CONST_ ## Name ## _name_obj = NULL; \ >- static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \ > static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL; > > DEFINE_CONSTS_FOR_NEW(md5) >@@ -64,19 +68,57 @@ DEFINE_CONSTS_FOR_NEW(sha512) > #endif > > >+/* LCOV_EXCL_START */ >+static PyObject * >+_setException(PyObject *exc) >+{ >+ unsigned long errcode; >+ const char *lib, *func, *reason; >+ >+ errcode = ERR_peek_last_error(); >+ if (!errcode) { >+ PyErr_SetString(exc, "unknown reasons"); >+ return NULL; >+ } >+ ERR_clear_error(); >+ >+ lib = ERR_lib_error_string(errcode); >+ func = ERR_func_error_string(errcode); >+ reason = ERR_reason_error_string(errcode); >+ >+ if (lib && func) { >+ PyErr_Format(exc, "[%s: %s] %s", lib, func, reason); >+ } >+ else if (lib) { >+ PyErr_Format(exc, "[%s] %s", lib, reason); >+ } >+ else { >+ PyErr_SetString(exc, reason); >+ } >+ return NULL; >+} >+/* LCOV_EXCL_STOP */ >+ > static EVPobject * > newEVPobject(PyObject *name) > { > EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype); >+ if (retval == NULL) { >+ return NULL; >+ } >+ >+ retval->ctx = EVP_MD_CTX_new(); >+ if (retval->ctx == NULL) { >+ PyErr_NoMemory(); >+ return NULL; >+ } > > /* save the name for .name to return */ >- if (retval != NULL) { >- Py_INCREF(name); >- retval->name = name; >+ Py_INCREF(name); >+ retval->name = name; > #ifdef WITH_THREAD >- retval->lock = NULL; >+ retval->lock = NULL; > #endif >- } > > return retval; > } >@@ -91,7 +133,7 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) > process = MUNCH_SIZE; > else > process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); >- EVP_DigestUpdate(&self->ctx, (const void*)cp, process); >+ EVP_DigestUpdate(self->ctx, (const void*)cp, process); > len -= process; > cp += process; > } >@@ -106,16 +148,19 @@ EVP_dealloc(EVPobject *self) > if (self->lock != NULL) > PyThread_free_lock(self->lock); > #endif >- EVP_MD_CTX_cleanup(&self->ctx); >+ EVP_MD_CTX_free(self->ctx); > Py_XDECREF(self->name); > PyObject_Del(self); > } > >-static void locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) >+static int >+locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) > { >+ int result; > ENTER_HASHLIB(self); >- EVP_MD_CTX_copy(new_ctx_p, &self->ctx); >+ result = EVP_MD_CTX_copy(new_ctx_p, self->ctx); > LEAVE_HASHLIB(self); >+ return result; > } > > /* External methods for a hash object */ >@@ -131,7 +176,9 @@ EVP_copy(EVPobject *self, PyObject *unused) > if ( (newobj = newEVPobject(self->name))==NULL) > return NULL; > >- locked_EVP_MD_CTX_copy(&newobj->ctx, self); >+ if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) { >+ return _setException(PyExc_ValueError); >+ } > return (PyObject *)newobj; > } > >@@ -142,16 +189,24 @@ static PyObject * > EVP_digest(EVPobject *self, PyObject *unused) > { > unsigned char digest[EVP_MAX_MD_SIZE]; >- EVP_MD_CTX temp_ctx; >+ EVP_MD_CTX *temp_ctx; > PyObject *retval; > unsigned int digest_size; > >- locked_EVP_MD_CTX_copy(&temp_ctx, self); >- digest_size = EVP_MD_CTX_size(&temp_ctx); >- EVP_DigestFinal(&temp_ctx, digest, NULL); >+ temp_ctx = EVP_MD_CTX_new(); >+ if (temp_ctx == NULL) { >+ PyErr_NoMemory(); >+ return NULL; >+ } >+ >+ if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { >+ return _setException(PyExc_ValueError); >+ } >+ digest_size = EVP_MD_CTX_size(temp_ctx); >+ EVP_DigestFinal(temp_ctx, digest, NULL); > > retval = PyBytes_FromStringAndSize((const char *)digest, digest_size); >- EVP_MD_CTX_cleanup(&temp_ctx); >+ EVP_MD_CTX_free(temp_ctx); > return retval; > } > >@@ -162,17 +217,25 @@ static PyObject * > EVP_hexdigest(EVPobject *self, PyObject *unused) > { > unsigned char digest[EVP_MAX_MD_SIZE]; >- EVP_MD_CTX temp_ctx; >+ EVP_MD_CTX *temp_ctx; > PyObject *retval; > char *hex_digest; > unsigned int i, j, digest_size; > >+ temp_ctx = EVP_MD_CTX_new(); >+ if (temp_ctx == NULL) { >+ PyErr_NoMemory(); >+ return NULL; >+ } >+ > /* Get the raw (binary) digest value */ >- locked_EVP_MD_CTX_copy(&temp_ctx, self); >- digest_size = EVP_MD_CTX_size(&temp_ctx); >- EVP_DigestFinal(&temp_ctx, digest, NULL); >+ if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { >+ return _setException(PyExc_ValueError); >+ } >+ digest_size = EVP_MD_CTX_size(temp_ctx); >+ EVP_DigestFinal(temp_ctx, digest, NULL); > >- EVP_MD_CTX_cleanup(&temp_ctx); >+ EVP_MD_CTX_free(temp_ctx); > > /* Allocate a new buffer */ > hex_digest = PyMem_Malloc(digest_size * 2 + 1); >@@ -241,7 +304,7 @@ static PyObject * > EVP_get_block_size(EVPobject *self, void *closure) > { > long block_size; >- block_size = EVP_MD_CTX_block_size(&self->ctx); >+ block_size = EVP_MD_CTX_block_size(self->ctx); > return PyLong_FromLong(block_size); > } > >@@ -249,7 +312,7 @@ static PyObject * > EVP_get_digest_size(EVPobject *self, void *closure) > { > long size; >- size = EVP_MD_CTX_size(&self->ctx); >+ size = EVP_MD_CTX_size(self->ctx); > return PyLong_FromLong(size); > } > >@@ -310,7 +373,7 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds) > PyBuffer_Release(&view); > return -1; > } >- EVP_DigestInit(&self->ctx, digest); >+ EVP_DigestInit(self->ctx, digest); > > self->name = name_obj; > Py_INCREF(self->name); >@@ -407,9 +470,9 @@ EVPnew(PyObject *name_obj, > return NULL; > > if (initial_ctx) { >- EVP_MD_CTX_copy(&self->ctx, initial_ctx); >+ EVP_MD_CTX_copy(self->ctx, initial_ctx); > } else { >- EVP_DigestInit(&self->ctx, digest); >+ EVP_DigestInit(self->ctx, digest); > } > > if (cp && len) { >@@ -475,6 +538,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict) > > #define PY_PBKDF2_HMAC 1 > >+#if !HAS_FAST_PKCS5_PBKDF2_HMAC > /* Improved implementation of PKCS5_PBKDF2_HMAC() > * > * PKCS5_PBKDF2_HMAC_fast() hashes the password exactly one time instead of >@@ -556,37 +620,8 @@ PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen, > HMAC_CTX_cleanup(&hctx_tpl); > return 1; > } >+#endif > >-/* LCOV_EXCL_START */ >-static PyObject * >-_setException(PyObject *exc) >-{ >- unsigned long errcode; >- const char *lib, *func, *reason; >- >- errcode = ERR_peek_last_error(); >- if (!errcode) { >- PyErr_SetString(exc, "unknown reasons"); >- return NULL; >- } >- ERR_clear_error(); >- >- lib = ERR_lib_error_string(errcode); >- func = ERR_func_error_string(errcode); >- reason = ERR_reason_error_string(errcode); >- >- if (lib && func) { >- PyErr_Format(exc, "[%s: %s] %s", lib, func, reason); >- } >- else if (lib) { >- PyErr_Format(exc, "[%s] %s", lib, reason); >- } >- else { >- PyErr_SetString(exc, reason); >- } >- return NULL; >-} >-/* LCOV_EXCL_STOP */ > > PyDoc_STRVAR(pbkdf2_hmac__doc__, > "pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key\n\ >@@ -668,10 +703,17 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict) > key = PyBytes_AS_STRING(key_obj); > > Py_BEGIN_ALLOW_THREADS >+#if HAS_FAST_PKCS5_PBKDF2_HMAC >+ retval = PKCS5_PBKDF2_HMAC((char*)password.buf, (int)password.len, >+ (unsigned char *)salt.buf, (int)salt.len, >+ iterations, digest, dklen, >+ (unsigned char *)key); >+#else > retval = PKCS5_PBKDF2_HMAC_fast((char*)password.buf, (int)password.len, > (unsigned char *)salt.buf, (int)salt.len, > iterations, digest, dklen, > (unsigned char *)key); >+#endif > Py_END_ALLOW_THREADS > > if (!retval) { >@@ -790,7 +832,7 @@ generate_hash_name_list(void) > if (CONST_ ## NAME ## _name_obj == NULL) { \ > CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \ > if (EVP_get_digestbyname(#NAME)) { \ >- CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \ >+ CONST_new_ ## NAME ## _ctx_p = EVP_MD_CTX_new(); \ > EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \ > } \ > } \ >diff --git a/Modules/_ssl.c b/Modules/_ssl.c >index 02971a7515..5721a5dc31 100644 >--- a/Modules/_ssl.c >+++ b/Modules/_ssl.c >@@ -55,6 +55,14 @@ static PySocketModule_APIObject PySocketModule; > #include <sys/poll.h> > #endif > >+/* Don't warn about deprecated functions */ >+#ifdef __GNUC__ >+#pragma GCC diagnostic ignored "-Wdeprecated-declarations" >+#endif >+#ifdef __clang__ >+#pragma clang diagnostic ignored "-Wdeprecated-declarations" >+#endif >+ > /* Include OpenSSL header files */ > #include "openssl/rsa.h" > #include "openssl/crypto.h" >@@ -90,6 +98,10 @@ struct py_ssl_library_code { > /* Include generated data (error codes) */ > #include "_ssl_data.h" > >+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) >+# define OPENSSL_VERSION_1_1 1 >+#endif >+ > /* Openssl comes with TLSv1.1 and TLSv1.2 between 1.0.0h and 1.0.1 > http://www.openssl.org/news/changelog.html > */ >@@ -108,6 +120,76 @@ struct py_ssl_library_code { > # define HAVE_SNI 0 > #endif > >+#ifndef INVALID_SOCKET /* MS defines this */ >+#define INVALID_SOCKET (-1) >+#endif >+ >+#ifdef OPENSSL_VERSION_1_1 >+/* OpenSSL 1.1.0+ */ >+#ifndef OPENSSL_NO_SSL2 >+#define OPENSSL_NO_SSL2 >+#endif >+#else /* OpenSSL < 1.1.0 */ >+#if defined(WITH_THREAD) >+#define HAVE_OPENSSL_CRYPTO_LOCK >+#endif >+ >+#define TLS_method SSLv23_method >+ >+static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) >+{ >+ return ne->set; >+} >+ >+#ifndef OPENSSL_NO_COMP >+static int COMP_get_type(const COMP_METHOD *meth) >+{ >+ return meth->type; >+} >+ >+static const char *COMP_get_name(const COMP_METHOD *meth) >+{ >+ return meth->name; >+} >+#endif >+ >+static pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) >+{ >+ return ctx->default_passwd_callback; >+} >+ >+static void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) >+{ >+ return ctx->default_passwd_callback_userdata; >+} >+ >+static int X509_OBJECT_get_type(X509_OBJECT *x) >+{ >+ return x->type; >+} >+ >+static X509 *X509_OBJECT_get0_X509(X509_OBJECT *x) >+{ >+ return x->data.x509; >+} >+ >+static int BIO_up_ref(BIO *b) >+{ >+ CRYPTO_add(&b->references, 1, CRYPTO_LOCK_BIO); >+ return 1; >+} >+ >+static STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *store) { >+ return store->objs; >+} >+ >+static X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *store) >+{ >+ return store->param; >+} >+#endif /* OpenSSL < 1.1.0 or LibreSSL */ >+ >+ > enum py_ssl_error { > /* these mirror ssl.h */ > PY_SSL_ERROR_NONE, >@@ -138,7 +220,7 @@ enum py_ssl_cert_requirements { > enum py_ssl_version { > PY_SSL_VERSION_SSL2, > PY_SSL_VERSION_SSL3=1, >- PY_SSL_VERSION_SSL23, >+ PY_SSL_VERSION_TLS, > #if HAVE_TLSv1_2 > PY_SSL_VERSION_TLS1, > PY_SSL_VERSION_TLS1_1, >@@ -504,7 +586,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, > PySSL_BEGIN_ALLOW_THREADS > self->ssl = SSL_new(ctx); > PySSL_END_ALLOW_THREADS >- SSL_set_app_data(self->ssl,self); >+ SSL_set_app_data(self->ssl, self); > SSL_set_fd(self->ssl, Py_SAFE_DOWNCAST(sock->sock_fd, SOCKET_T, int)); > mode = SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; > #ifdef SSL_MODE_AUTO_RETRY >@@ -691,7 +773,7 @@ _create_tuple_for_X509_NAME (X509_NAME *xname) > > /* check to see if we've gotten to a new RDN */ > if (rdn_level >= 0) { >- if (rdn_level != entry->set) { >+ if (rdn_level != X509_NAME_ENTRY_set(entry)) { > /* yes, new RDN */ > /* add old RDN to DN */ > rdnt = PyList_AsTuple(rdn); >@@ -708,7 +790,7 @@ _create_tuple_for_X509_NAME (X509_NAME *xname) > goto fail0; > } > } >- rdn_level = entry->set; >+ rdn_level = X509_NAME_ENTRY_set(entry); > > /* now add this attribute to the current RDN */ > name = X509_NAME_ENTRY_get_object(entry); >@@ -811,18 +893,18 @@ _get_peer_alt_names (X509 *certificate) { > goto fail; > } > >- p = ext->value->data; >+ p = X509_EXTENSION_get_data(ext)->data; > if (method->it) > names = (GENERAL_NAMES*) > (ASN1_item_d2i(NULL, > &p, >- ext->value->length, >+ X509_EXTENSION_get_data(ext)->length, > ASN1_ITEM_ptr(method->it))); > else > names = (GENERAL_NAMES*) > (method->d2i(NULL, > &p, >- ext->value->length)); >+ X509_EXTENSION_get_data(ext)->length)); > > for(j = 0; j < sk_GENERAL_NAME_num(names); j++) { > /* get a rendering of each name in the set of names */ >@@ -1033,13 +1115,11 @@ _get_crl_dp(X509 *certificate) { > int i, j; > PyObject *lst, *res = NULL; > >-#if OPENSSL_VERSION_NUMBER < 0x10001000L >- dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); >-#else >+#if OPENSSL_VERSION_NUMBER >= 0x10001000L > /* Calls x509v3_cache_extensions and sets up crldp */ > X509_check_ca(certificate); >- dps = certificate->crldp; > #endif >+ dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); > > if (dps == NULL) > return Py_None; >@@ -1403,6 +1483,71 @@ static PyObject *PySSL_cipher (PySSLSocket *self) { > return NULL; > } > >+/*[clinic input] >+_ssl._SSLSocket.shared_ciphers >+[clinic start generated code]*/ >+ >+static PyObject * >+_ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) >+/*[clinic end generated code: output=3d174ead2e42c4fd input=0bfe149da8fe6306]*/ >+{ >+ STACK_OF(SSL_CIPHER) *ciphers; >+ int i; >+ PyObject *res; >+ >+ ciphers = SSL_get_ciphers(self->ssl); >+ if (!ciphers) >+ Py_RETURN_NONE; >+ res = PyList_New(sk_SSL_CIPHER_num(ciphers)); >+ if (!res) >+ return NULL; >+ for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { >+ PyObject *tup = cipher_to_tuple(sk_SSL_CIPHER_value(ciphers, i)); >+ if (!tup) { >+ Py_DECREF(res); >+ return NULL; >+ } >+ PyList_SET_ITEM(res, i, tup); >+ } >+ return res; >+} >+ >+/*[clinic input] >+_ssl._SSLSocket.cipher >+[clinic start generated code]*/ >+ >+static PyObject * >+_ssl__SSLSocket_cipher_impl(PySSLSocket *self) >+/*[clinic end generated code: output=376417c16d0e5815 input=548fb0e27243796d]*/ >+{ >+ const SSL_CIPHER *current; >+ >+ if (self->ssl == NULL) >+ Py_RETURN_NONE; >+ current = SSL_get_current_cipher(self->ssl); >+ if (current == NULL) >+ Py_RETURN_NONE; >+ return cipher_to_tuple(current); >+} >+ >+/*[clinic input] >+_ssl._SSLSocket.version >+[clinic start generated code]*/ >+ >+static PyObject * >+_ssl__SSLSocket_version_impl(PySSLSocket *self) >+/*[clinic end generated code: output=178aed33193b2cdb input=900186a503436fd6]*/ >+{ >+ const char *version; >+ >+ if (self->ssl == NULL) >+ Py_RETURN_NONE; >+ version = SSL_get_version(self->ssl); >+ if (!strcmp(version, "unknown")) >+ Py_RETURN_NONE; >+ return PyUnicode_FromString(version); >+} >+ > #ifdef OPENSSL_NPN_NEGOTIATED > static PyObject *PySSL_selected_npn_protocol(PySSLSocket *self) { > const unsigned char *out; >@@ -1427,9 +1572,9 @@ static PyObject *PySSL_compression(PySSLSocket *self) { > if (self->ssl == NULL) > Py_RETURN_NONE; > comp_method = SSL_get_current_compression(self->ssl); >- if (comp_method == NULL || comp_method->type == NID_undef) >+ if (comp_method == NULL || COMP_get_type(comp_method) == NID_undef) > Py_RETURN_NONE; >- short_name = OBJ_nid2sn(comp_method->type); >+ short_name = COMP_get_name(comp_method); > if (short_name == NULL) > Py_RETURN_NONE; > return PyUnicode_DecodeFSDefault(short_name); >@@ -1977,7 +2122,7 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) > { > char *kwlist[] = {"protocol", NULL}; > PySSLContext *self; >- int proto_version = PY_SSL_VERSION_SSL23; >+ int proto_version = PY_SSL_VERSION_TLS; > long options; > SSL_CTX *ctx = NULL; > >@@ -2003,8 +2148,8 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) > else if (proto_version == PY_SSL_VERSION_SSL2) > ctx = SSL_CTX_new(SSLv2_method()); > #endif >- else if (proto_version == PY_SSL_VERSION_SSL23) >- ctx = SSL_CTX_new(SSLv23_method()); >+ else if (proto_version == PY_SSL_VERSION_TLS) >+ ctx = SSL_CTX_new(TLS_method()); > else > proto_version = -1; > PySSL_END_ALLOW_THREADS >@@ -2047,8 +2192,9 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) > #ifndef OPENSSL_NO_ECDH > /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use > prime256v1 by default. This is Apache mod_ssl's initialization >- policy, so we should be safe. */ >-#if defined(SSL_CTX_set_ecdh_auto) >+ policy, so we should be safe. OpenSSL 1.1 has it enabled by default. >+ */ >+#if defined(SSL_CTX_set_ecdh_auto) && !defined(OPENSSL_VERSION_1_1) > SSL_CTX_set_ecdh_auto(self->ctx, 1); > #else > { >@@ -2259,10 +2405,12 @@ static PyObject * > get_verify_flags(PySSLContext *self, void *c) > { > X509_STORE *store; >+ X509_VERIFY_PARAM *param; > unsigned long flags; > > store = SSL_CTX_get_cert_store(self->ctx); >- flags = X509_VERIFY_PARAM_get_flags(store->param); >+ param = X509_STORE_get0_param(store); >+ flags = X509_VERIFY_PARAM_get_flags(param); > return PyLong_FromUnsignedLong(flags); > } > >@@ -2270,22 +2418,24 @@ static int > set_verify_flags(PySSLContext *self, PyObject *arg, void *c) > { > X509_STORE *store; >+ X509_VERIFY_PARAM *param; > unsigned long new_flags, flags, set, clear; > > if (!PyArg_Parse(arg, "k", &new_flags)) > return -1; > store = SSL_CTX_get_cert_store(self->ctx); >- flags = X509_VERIFY_PARAM_get_flags(store->param); >+ param = X509_STORE_get0_param(store); >+ flags = X509_VERIFY_PARAM_get_flags(param); > clear = flags & ~new_flags; > set = ~flags & new_flags; > if (clear) { >- if (!X509_VERIFY_PARAM_clear_flags(store->param, clear)) { >+ if (!X509_VERIFY_PARAM_clear_flags(param, clear)) { > _setSSLError(NULL, 0, __FILE__, __LINE__); > return -1; > } > } > if (set) { >- if (!X509_VERIFY_PARAM_set_flags(store->param, set)) { >+ if (!X509_VERIFY_PARAM_set_flags(param, set)) { > _setSSLError(NULL, 0, __FILE__, __LINE__); > return -1; > } >@@ -2455,8 +2605,8 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds) > char *kwlist[] = {"certfile", "keyfile", "password", NULL}; > PyObject *certfile, *keyfile = NULL, *password = NULL; > PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; >- pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback; >- void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata; >+ pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx); >+ void *orig_passwd_userdata = SSL_CTX_get_default_passwd_cb_userdata(self->ctx); > _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 }; > int r; > >@@ -2587,8 +2737,9 @@ _add_ca_certs(PySSLContext *self, void *data, Py_ssize_t len, > cert = d2i_X509_bio(biobuf, NULL); > } else { > cert = PEM_read_bio_X509(biobuf, NULL, >- self->ctx->default_passwd_callback, >- self->ctx->default_passwd_callback_userdata); >+ SSL_CTX_get_default_passwd_cb(self->ctx), >+ SSL_CTX_get_default_passwd_cb_userdata(self->ctx) >+ ); > } > if (cert == NULL) { > break; >@@ -3036,25 +3187,24 @@ static PyObject * > cert_store_stats(PySSLContext *self) > { > X509_STORE *store; >+ STACK_OF(X509_OBJECT) *objs; > X509_OBJECT *obj; >- int x509 = 0, crl = 0, pkey = 0, ca = 0, i; >+ int x509 = 0, crl = 0, ca = 0, i; > > store = SSL_CTX_get_cert_store(self->ctx); >- for (i = 0; i < sk_X509_OBJECT_num(store->objs); i++) { >- obj = sk_X509_OBJECT_value(store->objs, i); >- switch (obj->type) { >+ objs = X509_STORE_get0_objects(store); >+ for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { >+ obj = sk_X509_OBJECT_value(objs, i); >+ switch (X509_OBJECT_get_type(obj)) { > case X509_LU_X509: > x509++; >- if (X509_check_ca(obj->data.x509)) { >+ if (X509_check_ca(X509_OBJECT_get0_X509(obj))) { > ca++; > } > break; > case X509_LU_CRL: > crl++; > break; >- case X509_LU_PKEY: >- pkey++; >- break; > default: > /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY. > * As far as I can tell they are internal states and never >@@ -3079,6 +3229,7 @@ get_ca_certs(PySSLContext *self, PyObject *args, PyObject *kwds) > { > char *kwlist[] = {"binary_form", NULL}; > X509_STORE *store; >+ STACK_OF(X509_OBJECT) *objs; > PyObject *ci = NULL, *rlist = NULL; > int i; > int binary_mode = 0; >@@ -3093,17 +3244,18 @@ get_ca_certs(PySSLContext *self, PyObject *args, PyObject *kwds) > } > > store = SSL_CTX_get_cert_store(self->ctx); >- for (i = 0; i < sk_X509_OBJECT_num(store->objs); i++) { >+ objs = X509_STORE_get0_objects(store); >+ for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { > X509_OBJECT *obj; > X509 *cert; > >- obj = sk_X509_OBJECT_value(store->objs, i); >- if (obj->type != X509_LU_X509) { >+ obj = sk_X509_OBJECT_value(objs, i); >+ if (X509_OBJECT_get_type(obj) != X509_LU_X509) { > /* not a x509 cert */ > continue; > } > /* CA for any purpose */ >- cert = obj->data.x509; >+ cert = X509_OBJECT_get0_X509(obj); > if (!X509_check_ca(cert)) { > continue; > } >@@ -3776,10 +3928,12 @@ static PyMethodDef PySSL_methods[] = { > }; > > >-#ifdef WITH_THREAD >+#ifdef HAVE_OPENSSL_CRYPTO_LOCK > > /* an implementation of OpenSSL threading operations in terms >- of the Python C thread library */ >+ * of the Python C thread library >+ * Only used up to 1.0.2. OpenSSL 1.1.0+ has its own locking code. >+ */ > > static PyThread_type_lock *_ssl_locks = NULL; > >@@ -3860,7 +4014,7 @@ static int _setup_ssl_threads(void) { > return 1; > } > >-#endif /* def HAVE_THREAD */ >+#endif /* HAVE_OPENSSL_CRYPTO_LOCK for WITH_THREAD && OpenSSL < 1.1.0 */ > > PyDoc_STRVAR(module_doc, > "Implementation module for SSL socket operations. See the socket module\n\ >@@ -3927,11 +4081,16 @@ PyInit__ssl(void) > SSL_load_error_strings(); > SSL_library_init(); > #ifdef WITH_THREAD >+#ifdef HAVE_OPENSSL_CRYPTO_LOCK > /* note that this will start threading if not already started */ > if (!_setup_ssl_threads()) { > return NULL; > } >+#elif OPENSSL_VERSION_1_1 && defined(OPENSSL_THREADS) >+ /* OpenSSL 1.1.0 builtin thread support is enabled */ >+ _ssl_locks_count++; > #endif >+#endif /* WITH_THREAD */ > OpenSSL_add_all_algorithms(); > > /* Add symbols to module dict */ >@@ -4075,7 +4234,9 @@ PyInit__ssl(void) > PY_SSL_VERSION_SSL3); > #endif > PyModule_AddIntConstant(m, "PROTOCOL_SSLv23", >- PY_SSL_VERSION_SSL23); >+ PY_SSL_VERSION_TLS); >+ PyModule_AddIntConstant(m, "PROTOCOL_TLS", >+ PY_SSL_VERSION_TLS); > PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", > PY_SSL_VERSION_TLS1); > #if HAVE_TLSv1_2
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 673960
:
562356
| 562358