Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 152efa2

Browse files
committed
Issue #8550: Add first class SSLContext objects to the ssl module.
1 parent 8eac60d commit 152efa2

7 files changed

Lines changed: 865 additions & 284 deletions

File tree

Doc/library/ssl.rst

Lines changed: 236 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ additional :meth:`read` and :meth:`write` methods, along with a method,
3636
connection, and a method, :meth:`cipher`, to retrieve the cipher being used for
3737
the secure connection.
3838

39+
For more sophisticated applications, the :class:`ssl.SSLContext` class
40+
helps manage settings and certificates, which can then be inherited
41+
by SSL sockets created through the :meth:`SSLContext.wrap_socket` method.
42+
43+
3944
Functions, Constants, and Exceptions
4045
------------------------------------
4146

@@ -64,19 +69,6 @@ Functions, Constants, and Exceptions
6469
connection. See the discussion of :ref:`ssl-certificates` for more
6570
information on how the certificate is stored in the ``certfile``.
6671

67-
Often the private key is stored in the same file as the certificate; in this
68-
case, only the ``certfile`` parameter need be passed. If the private key is
69-
stored in a separate file, both parameters must be used. If the private key
70-
is stored in the ``certfile``, it should come before the first certificate in
71-
the certificate chain::
72-
73-
-----BEGIN RSA PRIVATE KEY-----
74-
... (private key in base64 encoding) ...
75-
-----END RSA PRIVATE KEY-----
76-
-----BEGIN CERTIFICATE-----
77-
... (certificate in base64 PEM encoding) ...
78-
-----END CERTIFICATE-----
79-
8072
The parameter ``server_side`` is a boolean which identifies whether
8173
server-side or client-side behavior is desired from this socket.
8274

@@ -208,24 +200,36 @@ Functions, Constants, and Exceptions
208200

209201
.. data:: CERT_NONE
210202

211-
Value to pass to the ``cert_reqs`` parameter to :func:`sslobject` when no
212-
certificates will be required or validated from the other side of the socket
213-
connection.
203+
Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs``
204+
parameter to :func:`wrap_socket`. In this mode (the default), no
205+
certificates will be required from the other side of the socket connection.
206+
If a certificate is received from the other end, no attempt to validate it
207+
is made.
208+
209+
See the discussion of :ref:`ssl-security` below.
214210

215211
.. data:: CERT_OPTIONAL
216212

217-
Value to pass to the ``cert_reqs`` parameter to :func:`sslobject` when no
218-
certificates will be required from the other side of the socket connection,
219-
but if they are provided, will be validated. Note that use of this setting
220-
requires a valid certificate validation file also be passed as a value of the
221-
``ca_certs`` parameter.
213+
Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs``
214+
parameter to :func:`wrap_socket`. In this mode no certificates will be
215+
required from the other side of the socket connection; but if they
216+
are provided, validation will be attempted and an :class:`SSLError`
217+
will be raised on failure.
218+
219+
Use of this setting requires a valid set of CA certificates to
220+
be passed, either to :meth:`SSLContext.load_verify_locations` or as a
221+
value of the ``ca_certs`` parameter to :func:`wrap_socket`.
222222

223223
.. data:: CERT_REQUIRED
224224

225-
Value to pass to the ``cert_reqs`` parameter to :func:`sslobject` when
226-
certificates will be required from the other side of the socket connection.
227-
Note that use of this setting requires a valid certificate validation file
228-
also be passed as a value of the ``ca_certs`` parameter.
225+
Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs``
226+
parameter to :func:`wrap_socket`. In this mode, certificates are
227+
required from the other side of the socket connection; an :class:`SSLError`
228+
will be raised if no certificate is provided, or if its validation fails.
229+
230+
Use of this setting requires a valid set of CA certificates to
231+
be passed, either to :meth:`SSLContext.load_verify_locations` or as a
232+
value of the ``ca_certs`` parameter to :func:`wrap_socket`.
229233

230234
.. data:: PROTOCOL_SSLv2
231235

@@ -284,8 +288,8 @@ Functions, Constants, and Exceptions
284288
.. versionadded:: 3.2
285289

286290

287-
SSLSocket Objects
288-
-----------------
291+
SSL Sockets
292+
-----------
289293

290294
.. method:: SSLSocket.read(nbytes=1024, buffer=None)
291295

@@ -371,6 +375,83 @@ SSLSocket Objects
371375
returned socket should always be used for further communication with the
372376
other side of the connection, rather than the original socket.
373377

378+
379+
SSL Contexts
380+
------------
381+
382+
.. class:: SSLContext(protocol)
383+
384+
An object holding various data longer-lived than single SSL connections,
385+
such as SSL configuration options, certificate(s) and private key(s).
386+
You must pass *protocol* which must be one of the ``PROTOCOL_*`` constants
387+
defined in this module. :data:`PROTOCOL_SSLv23` is recommended for
388+
maximum interoperability.
389+
390+
:class:`SSLContext` objects have the following methods and attributes:
391+
392+
.. method:: SSLContext.load_cert_chain(certfile, keyfile=None)
393+
394+
Load a private key and the corresponding certificate. The *certfile*
395+
string must be the path to a single file in PEM format containing the
396+
certificate as well as any number of CA certificates needed to establish
397+
the certificate's authenticity. The *keyfile* string, if present, must
398+
point to a file containing the private key in. Otherwise the private
399+
key will be taken from *certfile* as well. See the discussion of
400+
:ref:`ssl-certificates` for more information on how the certificate
401+
is stored in the *certfile*.
402+
403+
An :class:`SSLError` is raised if the private key doesn't
404+
match with the certificate.
405+
406+
.. method:: SSLContext.load_verify_locations(cafile=None, capath=None)
407+
408+
Load a set of "certification authority" (CA) certificates used to validate
409+
other peers' certificates when :data:`verify_mode` is other than
410+
:data:`CERT_NONE`. At least one of *cafile* or *capath* must be specified.
411+
412+
The *cafile* string, if present, is the path to a file of concatenated
413+
CA certificates in PEM format. See the discussion of
414+
:ref:`ssl-certificates` for more information about how to arrange the
415+
certificates in this file.
416+
417+
The *capath* string, if present, is
418+
the path to a directory containing several CA certificates in PEM format,
419+
following an `OpenSSL specific layout
420+
<http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html>`_.
421+
422+
.. method:: SSLContext.set_ciphers(ciphers)
423+
424+
Set the available ciphers for sockets created with this context.
425+
It should be a string in the `OpenSSL cipher list format
426+
<http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`_.
427+
If no cipher can be selected (because compile-time options or other
428+
configuration forbids use of all the specified ciphers), an
429+
:class:`SSLError` will be raised.
430+
431+
.. note::
432+
when connected, the :meth:`SSLSocket.cipher` method of SSL sockets will
433+
give the currently selected cipher.
434+
435+
.. method:: SSLContext.wrap_socket(sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True)
436+
437+
Wrap an existing Python socket *sock* and return an :class:`SSLSocket`
438+
object. The SSL socket is tied to the context, its settings and
439+
certificates. The parameters *server_side*, *do_handshake_on_connect*
440+
and *suppress_ragged_eofs* have the same meaning as in the top-level
441+
:func:`wrap_socket` function.
442+
443+
.. attribute:: SSLContext.protocol
444+
445+
The protocol version chosen when constructing the context. This attribute
446+
is read-only.
447+
448+
.. attribute:: SSLContext.verify_mode
449+
450+
Whether to try to verify other peers' certificates and how to behave
451+
if verification fails. This attribute must be one of
452+
:data:`CERT_NONE`, :data:`CERT_OPTIONAL` or :data:`CERT_REQUIRED`.
453+
454+
374455
.. index:: single: certificates
375456

376457
.. index:: single: X509 certificate
@@ -416,6 +497,9 @@ and a footer line::
416497
... (certificate in base64 PEM encoding) ...
417498
-----END CERTIFICATE-----
418499

500+
Certificate chains
501+
^^^^^^^^^^^^^^^^^^
502+
419503
The Python files which contain certificates can contain a sequence of
420504
certificates, sometimes called a *certificate chain*. This chain should start
421505
with the specific certificate for the principal who "is" the client or server,
@@ -439,6 +523,9 @@ certification authority's certificate::
439523
... (the root certificate for the CA's issuer)...
440524
-----END CERTIFICATE-----
441525

526+
CA certificates
527+
^^^^^^^^^^^^^^^
528+
442529
If you are going to require validation of the other side of the connection's
443530
certificate, you need to provide a "CA certs" file, filled with the certificate
444531
chains for each issuer you are willing to trust. Again, this file just contains
@@ -458,6 +545,25 @@ peer is supposed to furnish the other certificates necessary to chain from its
458545
certificate to a root certificate. See :rfc:`4158` for more discussion of the
459546
way in which certification chains can be built.
460547

548+
Combined key and certificate
549+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
550+
551+
Often the private key is stored in the same file as the certificate; in this
552+
case, only the ``certfile`` parameter to :meth:`SSLContext.load_cert_chain`
553+
and :func:`wrap_socket` needs to be passed. If the private key is stored
554+
with the certificate, it should come before the first certificate in
555+
the certificate chain::
556+
557+
-----BEGIN RSA PRIVATE KEY-----
558+
... (private key in base64 encoding) ...
559+
-----END RSA PRIVATE KEY-----
560+
-----BEGIN CERTIFICATE-----
561+
... (certificate in base64 PEM encoding) ...
562+
-----END CERTIFICATE-----
563+
564+
Self-signed certificates
565+
^^^^^^^^^^^^^^^^^^^^^^^^
566+
461567
If you are going to create a server that provides SSL-encrypted connection
462568
services, you will need to acquire a certificate for that service. There are
463569
many ways of acquiring appropriate certificates, such as buying one from a
@@ -530,8 +636,7 @@ certificate, sends some bytes, and reads part of the response::
530636
print(pprint.pformat(ssl_sock.getpeercert()))
531637

532638
# Set a simple HTTP request -- use http.client in actual code.
533-
ssl_sock.write("""GET / HTTP/1.0\r
534-
Host: www.verisign.com\r\n\r\n""")
639+
ssl_sock.write(b"GET / HTTP/1.0\r\nHost: www.verisign.com\r\n\r\n")
535640

536641
# Read a chunk of data. Will not necessarily
537642
# read all the data returned by the server.
@@ -561,49 +666,133 @@ this::
561666

562667
which is a fairly poorly-formed ``subject`` field.
563668

669+
This other example first creates an SSL context, instructs it to verify
670+
certificates sent by peers, and feeds it a set of recognized certificate
671+
authorities (CA)::
672+
673+
>>> context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
674+
>>> context.verify_mode = ssl.CERT_OPTIONAL
675+
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
676+
677+
(it is assumed your operating system places a bundle of all CA certificates
678+
in ``/etc/ssl/certs/ca-bundle.crt``; if not, you'll get an error and have
679+
to adjust the location)
680+
681+
When you use the context to connect to a server, :const:`CERT_OPTIONAL`
682+
validates the server certificate: it ensures that the server certificate
683+
was signed with one of the CA certificates, and checks the signature for
684+
correctness::
685+
686+
>>> conn = context.wrap_socket(socket.socket(socket.AF_INET))
687+
>>> conn.connect(("linuxfr.org", 443))
688+
689+
You should then fetch the certificate and check its fields for conformity.
690+
Here, the ``commonName`` field in the ``subject`` matches the desired HTTPS
691+
host ``linuxfr.org``::
692+
693+
>>> pprint.pprint(conn.getpeercert())
694+
{'notAfter': 'Jun 26 21:41:46 2011 GMT',
695+
'subject': ((('commonName', 'linuxfr.org'),),),
696+
'subjectAltName': (('DNS', 'linuxfr.org'), ('othername', '<unsupported>'))}
697+
698+
Now that you are assured of its authenticity, you can proceed to talk with
699+
the server::
700+
701+
>>> conn.write(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n")
702+
38
703+
>>> pprint.pprint(conn.read().split(b"\r\n"))
704+
[b'HTTP/1.1 302 Found',
705+
b'Date: Sun, 16 May 2010 13:43:28 GMT',
706+
b'Server: Apache/2.2',
707+
b'Location: https://linuxfr.org/pub/',
708+
b'Vary: Accept-Encoding',
709+
b'Connection: close',
710+
b'Content-Type: text/html; charset=iso-8859-1',
711+
b'',
712+
b'']
713+
714+
715+
See the discussion of :ref:`ssl-security` below.
716+
717+
564718
Server-side operation
565719
^^^^^^^^^^^^^^^^^^^^^
566720

567-
For server operation, typically you'd need to have a server certificate, and
568-
private key, each in a file. You'd open a socket, bind it to a port, call
569-
:meth:`listen` on it, then start waiting for clients to connect::
721+
For server operation, typically you'll need to have a server certificate, and
722+
private key, each in a file. You'll first create a context holding the key
723+
and the certificate, so that clients can check your authenticity. Then
724+
you'll open a socket, bind it to a port, call :meth:`listen` on it, and start
725+
waiting for clients to connect::
570726

571727
import socket, ssl
572728

729+
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
730+
context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile")
731+
573732
bindsocket = socket.socket()
574733
bindsocket.bind(('myaddr.mydomain.com', 10023))
575734
bindsocket.listen(5)
576735

577-
When one did, you'd call :meth:`accept` on the socket to get the new socket from
578-
the other end, and use :func:`wrap_socket` to create a server-side SSL context
579-
for it::
736+
When a client connects, you'll call :meth:`accept` on the socket to get the
737+
new socket from the other end, and use the context's :meth:`SSLContext.wrap_socket`
738+
method to create a server-side SSL socket for the connection::
580739

581740
while True:
582741
newsocket, fromaddr = bindsocket.accept()
583-
connstream = ssl.wrap_socket(newsocket,
584-
server_side=True,
585-
certfile="mycertfile",
586-
keyfile="mykeyfile",
587-
ssl_version=ssl.PROTOCOL_TLSv1)
588-
deal_with_client(connstream)
589-
590-
Then you'd read data from the ``connstream`` and do something with it till you
742+
connstream = context.wrap_socket(newsocket, server_side=True)
743+
try:
744+
deal_with_client(connstream)
745+
finally:
746+
connstream.close()
747+
748+
Then you'll read data from the ``connstream`` and do something with it till you
591749
are finished with the client (or the client is finished with you)::
592750

593751
def deal_with_client(connstream):
594-
595752
data = connstream.read()
596-
# null data means the client is finished with us
753+
# empty data means the client is finished with us
597754
while data:
598755
if not do_something(connstream, data):
599756
# we'll assume do_something returns False
600757
# when we're finished with client
601758
break
602759
data = connstream.read()
603760
# finished with client
604-
connstream.close()
605761

606-
And go back to listening for new client connections.
762+
And go back to listening for new client connections (of course, a real server
763+
would probably handle each client connection in a separate thread, or put
764+
the sockets in non-blocking mode and use an event loop).
765+
766+
767+
.. _ssl-security:
768+
769+
Security considerations
770+
-----------------------
771+
772+
Verifying certificates
773+
^^^^^^^^^^^^^^^^^^^^^^
774+
775+
:const:`CERT_NONE` is the default. Since it does not authenticate the other
776+
peer, it can be insecure, especially in client mode where most of time you
777+
would like to ensure the authenticity of the server you're talking to.
778+
Therefore, when in client mode, it is highly recommended to use
779+
:const:`CERT_REQUIRED`. However, it is in itself not sufficient; you also
780+
have to check that the server certificate (obtained with
781+
:meth:`SSLSocket.getpeercert`) matches the desired service. The exact way
782+
of doing so depends on the higher-level protocol used; for example, with
783+
HTTPS, you'll check that the host name in the URL matches either the
784+
``commonName`` field in the ``subjectName``, or one of the ``DNS`` fields
785+
in the ``subjectAltName``.
786+
787+
In server mode, if you want to authenticate your clients using the SSL layer
788+
(rather than using a higher-level authentication mechanism), you'll also have
789+
to specify :const:`CERT_REQUIRED` and similarly check the client certificate.
790+
791+
.. note::
792+
793+
In client mode, :const:`CERT_OPTIONAL` and :const:`CERT_REQUIRED` are
794+
equivalent unless anonymous ciphers are enabled (they are disabled
795+
by default).
607796

608797

609798
.. seealso::

0 commit comments

Comments
 (0)