Skip to content

Commit da16e6e

Browse files
committed
Issue #22660: update various mentions in the ssl module documentation.
2 parents af66128 + 41a0280 commit da16e6e

File tree

1 file changed

+95
-115
lines changed

1 file changed

+95
-115
lines changed

Doc/library/ssl.rst

Lines changed: 95 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,9 @@ instead.
201201
.. note::
202202

203203
Which connections succeed will vary depending on the version of
204-
OpenSSL. For instance, in some older versions of OpenSSL (such
205-
as 0.9.7l on OS X 10.4), an SSLv2 client could not connect to an
206-
SSLv23 server. Another example: beginning with OpenSSL 1.0.0,
207-
an SSLv23 client will not actually attempt SSLv2 connections
208-
unless you explicitly enable SSLv2 ciphers; for example, you
209-
might specify ``"ALL"`` or ``"SSLv2"`` as the *ciphers* parameter
210-
to enable them.
204+
OpenSSL. For example, beginning with OpenSSL 1.0.0, an SSLv23 client
205+
will not actually attempt SSLv2 connections unless you explicitly
206+
enable SSLv2 ciphers (which is not recommended, as SSLv2 is broken).
211207

212208
The *ciphers* parameter sets the available ciphers for this SSL object.
213209
It should be a string in the `OpenSSL cipher list format
@@ -550,6 +546,11 @@ Constants
550546

551547
.. versionadded:: 3.4
552548

549+
.. data:: PROTOCOL_SSLv23
550+
551+
Selects the highest protocol version that both the client and server support.
552+
Despite the name, this option can select "TLS" protocols as well as "SSL".
553+
553554
.. data:: PROTOCOL_SSLv2
554555

555556
Selects SSL version 2 as the channel encryption protocol.
@@ -561,17 +562,13 @@ Constants
561562

562563
SSL version 2 is insecure. Its use is highly discouraged.
563564

564-
.. data:: PROTOCOL_SSLv23
565+
.. data:: PROTOCOL_SSLv3
565566

566-
Selects SSL version 2 or 3 as the channel encryption protocol. This is a
567-
setting to use with servers for maximum compatibility with the other end of
568-
an SSL connection, but it may cause the specific ciphers chosen for the
569-
encryption to be of fairly low quality.
567+
Selects SSL version 3 as the channel encryption protocol.
570568

571-
.. data:: PROTOCOL_SSLv3
569+
.. warning::
572570

573-
Selects SSL version 3 as the channel encryption protocol. For clients, this
574-
is the maximally compatible SSL variant.
571+
SSL version 3 is insecure. Its use is highly discouraged.
575572

576573
.. data:: PROTOCOL_TLSv1
577574

@@ -586,9 +583,9 @@ Constants
586583

587584
.. data:: PROTOCOL_TLSv1_2
588585

589-
Selects TLS version 1.2 as the channel encryption protocol. This is the most
590-
modern version, and probably the best choice for maximum protection, if both
591-
sides can speak it. Available only with openssl version 1.0.1+.
586+
Selects TLS version 1.2 as the channel encryption protocol. This is the
587+
most modern version, and probably the best choice for maximum protection,
588+
if both sides can speak it. Available only with openssl version 1.0.1+.
592589

593590
.. versionadded:: 3.4
594591

@@ -683,9 +680,8 @@ Constants
683680
.. data:: HAS_SNI
684681

685682
Whether the OpenSSL library has built-in support for the *Server Name
686-
Indication* extension to the SSLv3 and TLSv1 protocols (as defined in
687-
:rfc:`4366`). When true, you can use the *server_hostname* argument to
688-
:meth:`SSLContext.wrap_socket`.
683+
Indication* extension (as defined in :rfc:`4366`). When true, you can
684+
use the *server_hostname* argument to :meth:`SSLContext.wrap_socket`.
689685

690686
.. versionadded:: 3.2
691687

@@ -1516,118 +1512,100 @@ should use the following idiom::
15161512
Client-side operation
15171513
^^^^^^^^^^^^^^^^^^^^^
15181514

1519-
This example connects to an SSL server and prints the server's certificate::
1520-
1521-
import socket, ssl, pprint
1522-
1523-
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1524-
# require a certificate from the server
1525-
ssl_sock = ssl.wrap_socket(s,
1526-
ca_certs="/etc/ca_certs_file",
1527-
cert_reqs=ssl.CERT_REQUIRED)
1528-
ssl_sock.connect(('www.verisign.com', 443))
1529-
1530-
pprint.pprint(ssl_sock.getpeercert())
1531-
# note that closing the SSLSocket will also close the underlying socket
1532-
ssl_sock.close()
1533-
1534-
As of January 6, 2012, the certificate printed by this program looks like
1535-
this::
1536-
1537-
{'issuer': ((('countryName', 'US'),),
1538-
(('organizationName', 'VeriSign, Inc.'),),
1539-
(('organizationalUnitName', 'VeriSign Trust Network'),),
1540-
(('organizationalUnitName',
1541-
'Terms of use at https://www.verisign.com/rpa (c)06'),),
1542-
(('commonName',
1543-
'VeriSign Class 3 Extended Validation SSL SGC CA'),)),
1544-
'notAfter': 'May 25 23:59:59 2012 GMT',
1545-
'notBefore': 'May 26 00:00:00 2010 GMT',
1546-
'serialNumber': '53D2BEF924A7245E83CA01E46CAA2477',
1547-
'subject': ((('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
1548-
(('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
1549-
(('businessCategory', 'V1.0, Clause 5.(b)'),),
1550-
(('serialNumber', '2497886'),),
1551-
(('countryName', 'US'),),
1552-
(('postalCode', '94043'),),
1553-
(('stateOrProvinceName', 'California'),),
1554-
(('localityName', 'Mountain View'),),
1555-
(('streetAddress', '487 East Middlefield Road'),),
1556-
(('organizationName', 'VeriSign, Inc.'),),
1557-
(('organizationalUnitName', ' Production Security Services'),),
1558-
(('commonName', 'www.verisign.com'),)),
1559-
'subjectAltName': (('DNS', 'www.verisign.com'),
1560-
('DNS', 'verisign.com'),
1561-
('DNS', 'www.verisign.net'),
1562-
('DNS', 'verisign.net'),
1563-
('DNS', 'www.verisign.mobi'),
1564-
('DNS', 'verisign.mobi'),
1565-
('DNS', 'www.verisign.eu'),
1566-
('DNS', 'verisign.eu')),
1567-
'version': 3}
1515+
This example creates a SSL context with the recommended security settings
1516+
for client sockets, including automatic certificate verification::
1517+
1518+
>>> context = ssl.create_default_context()
15681519

1569-
This other example first creates an SSL context, instructs it to verify
1570-
certificates sent by peers, and feeds it a set of recognized certificate
1571-
authorities (CA)::
1520+
If you prefer to tune security settings yourself, you might create
1521+
a context from scratch (but beware that you might not get the settings
1522+
right)::
15721523

15731524
>>> context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
15741525
>>> context.verify_mode = ssl.CERT_REQUIRED
1526+
>>> context.check_hostname = True
15751527
>>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
15761528

1577-
(it is assumed your operating system places a bundle of all CA certificates
1578-
in ``/etc/ssl/certs/ca-bundle.crt``; if not, you'll get an error and have
1579-
to adjust the location)
1529+
(this snippet assumes your operating system places a bundle of all CA
1530+
certificates in ``/etc/ssl/certs/ca-bundle.crt``; if not, you'll get an
1531+
error and have to adjust the location)
15801532

15811533
When you use the context to connect to a server, :const:`CERT_REQUIRED`
15821534
validates the server certificate: it ensures that the server certificate
15831535
was signed with one of the CA certificates, and checks the signature for
15841536
correctness::
15851537

1586-
>>> conn = context.wrap_socket(socket.socket(socket.AF_INET))
1587-
>>> conn.connect(("linuxfr.org", 443))
1538+
>>> conn = context.wrap_socket(socket.socket(socket.AF_INET),
1539+
... server_hostname="www.python.org")
1540+
>>> conn.connect(("www.python.org", 443))
15881541

1589-
You should then fetch the certificate and check its fields for conformity::
1542+
You may then fetch the certificate::
15901543

15911544
>>> cert = conn.getpeercert()
1592-
>>> ssl.match_hostname(cert, "linuxfr.org")
15931545

15941546
Visual inspection shows that the certificate does identify the desired service
1595-
(that is, the HTTPS host ``linuxfr.org``)::
1547+
(that is, the HTTPS host ``www.python.org``)::
15961548

15971549
>>> pprint.pprint(cert)
1598-
{'issuer': ((('organizationName', 'CAcert Inc.'),),
1599-
(('organizationalUnitName', 'http://www.CAcert.org'),),
1600-
(('commonName', 'CAcert Class 3 Root'),)),
1601-
'notAfter': 'Jun 7 21:02:24 2013 GMT',
1602-
'notBefore': 'Jun 8 21:02:24 2011 GMT',
1603-
'serialNumber': 'D3E9',
1604-
'subject': ((('commonName', 'linuxfr.org'),),),
1605-
'subjectAltName': (('DNS', 'linuxfr.org'),
1606-
('othername', '<unsupported>'),
1607-
('DNS', 'linuxfr.org'),
1608-
('othername', '<unsupported>'),
1609-
('DNS', 'dev.linuxfr.org'),
1610-
('othername', '<unsupported>'),
1611-
('DNS', 'prod.linuxfr.org'),
1612-
('othername', '<unsupported>'),
1613-
('DNS', 'alpha.linuxfr.org'),
1614-
('othername', '<unsupported>'),
1615-
('DNS', '*.linuxfr.org'),
1616-
('othername', '<unsupported>')),
1550+
{'OCSP': ('http://ocsp.digicert.com',),
1551+
'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',),
1552+
'crlDistributionPoints': ('http://crl3.digicert.com/sha2-ev-server-g1.crl',
1553+
'http://crl4.digicert.com/sha2-ev-server-g1.crl'),
1554+
'issuer': ((('countryName', 'US'),),
1555+
(('organizationName', 'DigiCert Inc'),),
1556+
(('organizationalUnitName', 'www.digicert.com'),),
1557+
(('commonName', 'DigiCert SHA2 Extended Validation Server CA'),)),
1558+
'notAfter': 'Sep 9 12:00:00 2016 GMT',
1559+
'notBefore': 'Sep 5 00:00:00 2014 GMT',
1560+
'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26',
1561+
'subject': ((('businessCategory', 'Private Organization'),),
1562+
(('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
1563+
(('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
1564+
(('serialNumber', '3359300'),),
1565+
(('streetAddress', '16 Allen Rd'),),
1566+
(('postalCode', '03894-4801'),),
1567+
(('countryName', 'US'),),
1568+
(('stateOrProvinceName', 'NH'),),
1569+
(('localityName', 'Wolfeboro,'),),
1570+
(('organizationName', 'Python Software Foundation'),),
1571+
(('commonName', 'www.python.org'),)),
1572+
'subjectAltName': (('DNS', 'www.python.org'),
1573+
('DNS', 'python.org'),
1574+
('DNS', 'pypi.python.org'),
1575+
('DNS', 'docs.python.org'),
1576+
('DNS', 'testpypi.python.org'),
1577+
('DNS', 'bugs.python.org'),
1578+
('DNS', 'wiki.python.org'),
1579+
('DNS', 'hg.python.org'),
1580+
('DNS', 'mail.python.org'),
1581+
('DNS', 'packaging.python.org'),
1582+
('DNS', 'pythonhosted.org'),
1583+
('DNS', 'www.pythonhosted.org'),
1584+
('DNS', 'test.pythonhosted.org'),
1585+
('DNS', 'us.pycon.org'),
1586+
('DNS', 'id.python.org')),
16171587
'version': 3}
16181588

1619-
Now that you are assured of its authenticity, you can proceed to talk with
1620-
the server::
1589+
Now the SSL channel is established and the certificate verified, you can
1590+
proceed to talk with the server::
16211591

16221592
>>> conn.sendall(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n")
16231593
>>> pprint.pprint(conn.recv(1024).split(b"\r\n"))
1624-
[b'HTTP/1.1 302 Found',
1625-
b'Date: Sun, 16 May 2010 13:43:28 GMT',
1626-
b'Server: Apache/2.2',
1627-
b'Location: https://linuxfr.org/pub/',
1628-
b'Vary: Accept-Encoding',
1594+
[b'HTTP/1.1 200 OK',
1595+
b'Date: Sat, 18 Oct 2014 18:27:20 GMT',
1596+
b'Server: nginx',
1597+
b'Content-Type: text/html; charset=utf-8',
1598+
b'X-Frame-Options: SAMEORIGIN',
1599+
b'Content-Length: 45679',
1600+
b'Accept-Ranges: bytes',
1601+
b'Via: 1.1 varnish',
1602+
b'Age: 2188',
1603+
b'X-Served-By: cache-lcy1134-LCY',
1604+
b'X-Cache: HIT',
1605+
b'X-Cache-Hits: 11',
1606+
b'Vary: Cookie',
1607+
b'Strict-Transport-Security: max-age=63072000; includeSubDomains',
16291608
b'Connection: close',
1630-
b'Content-Type: text/html; charset=iso-8859-1',
16311609
b'',
16321610
b'']
16331611

@@ -1645,7 +1623,7 @@ waiting for clients to connect::
16451623

16461624
import socket, ssl
16471625

1648-
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1626+
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
16491627
context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile")
16501628

16511629
bindsocket = socket.socket()
@@ -1941,16 +1919,18 @@ to specify :const:`CERT_REQUIRED` and similarly check the client certificate.
19411919
Protocol versions
19421920
'''''''''''''''''
19431921

1944-
SSL version 2 is considered insecure and is therefore dangerous to use. If
1945-
you want maximum compatibility between clients and servers, it is recommended
1946-
to use :const:`PROTOCOL_SSLv23` as the protocol version and then disable
1947-
SSLv2 explicitly using the :data:`SSLContext.options` attribute::
1922+
SSL versions 2 and 3 are considered insecure and are therefore dangerous to
1923+
use. If you want maximum compatibility between clients and servers, it is
1924+
recommended to use :const:`PROTOCOL_SSLv23` as the protocol version and then
1925+
disable SSLv2 and SSLv3 explicitly using the :data:`SSLContext.options`
1926+
attribute::
19481927

19491928
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
19501929
context.options |= ssl.OP_NO_SSLv2
1930+
context.options |= ssl.OP_NO_SSLv3
19511931

1952-
The SSL context created above will allow SSLv3 and TLSv1 (and later, if
1953-
supported by your system) connections, but not SSLv2.
1932+
The SSL context created above will only allow TLSv1 and later (if
1933+
supported by your system) connections.
19541934

19551935
Cipher selection
19561936
''''''''''''''''

0 commit comments

Comments
 (0)