Skip to content

Commit 08802a1

Browse files
committed
Issue #21965: Add support for in-memory SSL to the ssl module.
Patch by Geert Jansen.
1 parent 86b4a3e commit 08802a1

File tree

5 files changed

+926
-102
lines changed

5 files changed

+926
-102
lines changed

Doc/library/ssl.rst

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,29 @@ the specification of normal, OS-level sockets. See especially the
803803

804804
SSL sockets also have the following additional methods and attributes:
805805

806+
.. method:: SSLSocket.read(len=0, buffer=None)
807+
808+
Read up to *len* bytes of data from the SSL socket and return the result as
809+
a ``bytes`` instance. If *buffer* is specified, then read into the buffer
810+
instead, and return the number of bytes read.
811+
812+
.. method:: SSLSocket.write(buf)
813+
814+
Write *buf* to the SSL socket and return the number of bytes written. The
815+
*buf* argument must be an object supporting the buffer interface.
816+
817+
.. note::
818+
819+
The :meth:`~SSLSocket.read` and :meth:`~SSLSocket.write` methods are the
820+
low-level methods that read and write unencrypted, application-level data
821+
and and decrypt/encrypt it to encrypted, wire-level data. These methods
822+
require an active SSL connection, i.e. the handshake was completed and
823+
:meth:`SSLSocket.unwrap` was not called.
824+
825+
Normally you should use the socket API methods like
826+
:meth:`~socket.socket.recv` and :meth:`~socket.socket.send` instead of these
827+
methods.
828+
806829
.. method:: SSLSocket.do_handshake()
807830

808831
Perform the SSL setup handshake.
@@ -935,6 +958,11 @@ SSL sockets also have the following additional methods and attributes:
935958

936959
.. versionadded:: 3.5
937960

961+
.. method:: SSLSocket.pending()
962+
963+
Returns the number of already decrypted bytes available for read, pending on
964+
the connection.
965+
938966
.. attribute:: SSLSocket.context
939967

940968
The :class:`SSLContext` object this SSL socket is tied to. If the SSL
@@ -944,6 +972,22 @@ SSL sockets also have the following additional methods and attributes:
944972

945973
.. versionadded:: 3.2
946974

975+
.. attribute:: SSLSocket.server_side
976+
977+
A boolean which is ``True`` for server-side sockets and ``False`` for
978+
client-side sockets.
979+
980+
.. versionadded:: 3.5
981+
982+
.. attribute:: SSLSocket.server_hostname
983+
984+
A ``bytes`` instance containing the ``'idna'`` encoded version of the
985+
hostname specified in the *server_hostname* argument in
986+
:meth:`SSLContext.wrap_socket`. If no *server_hostname* was specified, this
987+
attribute will be ``None``.
988+
989+
.. versionadded:: 3.5
990+
947991

948992
SSL Contexts
949993
------------
@@ -1670,6 +1714,130 @@ thus several things you need to be aware of:
16701714
select.select([], [sock], [])
16711715

16721716

1717+
Memory BIO Support
1718+
------------------
1719+
1720+
.. versionadded:: 3.5
1721+
1722+
Ever since the SSL module was introduced in Python 2.6, the :class:`SSLSocket`
1723+
class has provided two related but distinct areas of functionality:
1724+
1725+
- SSL protocol handling
1726+
- Network IO
1727+
1728+
The network IO API is identical to that provided by :class:`socket.socket`,
1729+
from which :class:`SSLSocket` also inherits. This allows an SSL socket to be
1730+
used as a drop-in replacement for a regular socket, making it very easy to add
1731+
SSL support to an existing application.
1732+
1733+
Combining SSL protocol handling and network IO usually works well, but there
1734+
are some cases where it doesn't. An example is async IO frameworks that want to
1735+
use a different IO multiplexing model than the "select/poll on a file
1736+
descriptor" (readiness based) model that is assumed by :class:`socket.socket`
1737+
and by the internal OpenSSL socket IO routines. This is mostly relevant for
1738+
platforms like Windows where this model is not efficient. For this purpose, a
1739+
reduced scope variant of :class:`SSLSocket` called :class:`SSLObject` is
1740+
provided.
1741+
1742+
.. class:: SSLObject
1743+
1744+
A reduced-scope variant of :class:`SSLSocket` representing an SSL protocol
1745+
instance that does not contain any network IO methods.
1746+
1747+
The following methods are available from :class:`SSLSocket`:
1748+
1749+
- :attr:`~SSLSocket.context`
1750+
- :attr:`~SSLSocket.server_side`
1751+
- :attr:`~SSLSocket.server_hostname`
1752+
- :meth:`~SSLSocket.read`
1753+
- :meth:`~SSLSocket.write`
1754+
- :meth:`~SSLSocket.getpeercert`
1755+
- :meth:`~SSLSocket.selected_npn_protocol`
1756+
- :meth:`~SSLSocket.cipher`
1757+
- :meth:`~SSLSocket.compression`
1758+
- :meth:`~SSLSocket.pending`
1759+
- :meth:`~SSLSocket.do_handshake`
1760+
- :meth:`~SSLSocket.unwrap`
1761+
- :meth:`~SSLSocket.get_channel_binding`
1762+
1763+
An SSLObject communicates with the outside world using memory buffers. The
1764+
class :class:`MemoryBIO` provides a memory buffer that can be used for this
1765+
purpose. It wraps an OpenSSL memory BIO (Basic IO) object:
1766+
1767+
.. class:: MemoryBIO
1768+
1769+
A memory buffer that can be used to pass data between Python and an SSL
1770+
protocol instance.
1771+
1772+
.. attribute:: MemoryBIO.pending
1773+
1774+
Return the number of bytes currently in the memory buffer.
1775+
1776+
.. attribute:: MemoryBIO.eof
1777+
1778+
A boolean indicating whether the memory BIO is current at the end-of-file
1779+
position.
1780+
1781+
.. method:: MemoryBIO.read(n=-1)
1782+
1783+
Read up to *n* bytes from the memory buffer. If *n* is not specified or
1784+
negative, all bytes are returned.
1785+
1786+
.. method:: MemoryBIO.write(buf)
1787+
1788+
Write the bytes from *buf* to the memory BIO. The *buf* argument must be an
1789+
object supporting the buffer protocol.
1790+
1791+
The return value is the number of bytes written, which is always equal to
1792+
the length of *buf*.
1793+
1794+
.. method:: MemoryBIO.write_eof()
1795+
1796+
Write an EOF marker to the memory BIO. After this method has been called, it
1797+
is illegal to call :meth:`~MemoryBIO.write`. The attribute :attr:`eof` will
1798+
become true after all data currently in the buffer has been read.
1799+
1800+
An :class:`SSLObject` instance can be created using the
1801+
:meth:`~SSLContext.wrap_bio` method. This method will create the
1802+
:class:`SSLObject` instance and bind it to a pair of BIOs. The *incoming* BIO
1803+
is used to pass data from Python to the SSL protocol instance, while the
1804+
*outgoing* BIO is used to pass data the other way around.
1805+
1806+
.. method:: SSLContext.wrap_bio(incoming, outgoing, server_side=False, \
1807+
server_hostname=None)
1808+
1809+
Create a new :class:`SSLObject` instance by wrapping the BIO objects
1810+
*incoming* and *outgoing*. The SSL routines will read input data from the
1811+
incoming BIO and write data to the outgoing BIO.
1812+
1813+
The *server_side* and *server_hostname* parameters have the same meaning as
1814+
in :meth:`SSLContext.wrap_socket`.
1815+
1816+
Some notes related to the use of :class:`SSLObject`:
1817+
1818+
- All IO on an :class:`SSLObject` is non-blocking. This means that for example
1819+
:meth:`~SSLSocket.read` will raise an :exc:`SSLWantReadError` if it needs
1820+
more data than the incoming BIO has available.
1821+
1822+
- There is no module-level ``wrap_bio`` call like there is for
1823+
:meth:`~SSLContext.wrap_socket`. An :class:`SSLObject` is always created via
1824+
an :class:`SSLContext`.
1825+
1826+
- There is no *do_handshake_on_connect* machinery. You must always manually
1827+
call :meth:`~SSLSocket.do_handshake` to start the handshake.
1828+
1829+
- There is no handling of *suppress_ragged_eofs*. All end-of-file conditions
1830+
that are in violation of the protocol are reported via the :exc:`SSLEOFError`
1831+
exception.
1832+
1833+
- The method :meth:`~SSLSocket.unwrap` call does not return anything, unlike
1834+
for an SSL socket where it returns the underlying socket.
1835+
1836+
- The *server_name_callback* callback passed to
1837+
:meth:`SSLContext.set_servername_callback` will get an :class:`SSLObject`
1838+
instance instead of a :class:`SSLSocket` instance as its first parameter.
1839+
1840+
16731841
.. _ssl-security:
16741842

16751843
Security considerations

0 commit comments

Comments
 (0)