@@ -45,11 +45,27 @@ Functions, Constants, and Exceptions
4545
4646.. exception :: SSLError
4747
48- Raised to signal an error from the underlying SSL implementation. This
49- signifies some problem in the higher-level encryption and authentication
50- layer that's superimposed on the underlying network connection. This error
48+ Raised to signal an error from the underlying SSL implementation
49+ (currently provided by the OpenSSL library). This signifies some
50+ problem in the higher-level encryption and authentication layer that's
51+ superimposed on the underlying network connection. This error
5152 is a subtype of :exc: `socket.error `, which in turn is a subtype of
52- :exc: `IOError `.
53+ :exc: `IOError `. The error code and message of :exc: `SSLError ` instances
54+ are provided by the OpenSSL library.
55+
56+ .. exception :: CertificateError
57+
58+ Raised to signal an error with a certificate (such as mismatching
59+ hostname). Certificate errors detected by OpenSSL, though, raise
60+ an :exc: `SSLError `.
61+
62+
63+ Socket creation
64+ ^^^^^^^^^^^^^^^
65+
66+ The following function allows for standalone socket creation. Starting from
67+ Python 3.2, it can be more flexible to use :meth: `SSLContext.wrap_socket `
68+ instead.
5369
5470.. function :: wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version={see docs}, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None)
5571
@@ -139,6 +155,9 @@ Functions, Constants, and Exceptions
139155 .. versionchanged :: 3.2
140156 New optional argument *ciphers *.
141157
158+ Random generation
159+ ^^^^^^^^^^^^^^^^^
160+
142161.. function :: RAND_status()
143162
144163 Returns True if the SSL pseudo-random number generator has been seeded with
@@ -164,6 +183,32 @@ Functions, Constants, and Exceptions
164183 string (so you can always use :const: `0.0 `). See :rfc: `1750 ` for more
165184 information on sources of entropy.
166185
186+ Certificate handling
187+ ^^^^^^^^^^^^^^^^^^^^
188+
189+ .. function :: match_hostname(cert, hostname)
190+
191+ Verify that *cert * (in decoded format as returned by
192+ :meth: `SSLSocket.getpeercert `) matches the given *hostname *. The rules
193+ applied are those for checking the identity of HTTPS servers as outlined
194+ in :rfc: `2818 `, except that IP addresses are not currently supported.
195+ In addition to HTTPS, this function should be suitable for checking the
196+ identity of servers in various SSL-based protocols such as FTPS, IMAPS,
197+ POPS and others.
198+
199+ :exc: `CertificateError ` is raised on failure. On success, the function
200+ returns nothing::
201+
202+ >>> cert = {'subject': ((('commonName', 'example.com'),),)}
203+ >>> ssl.match_hostname(cert, "example.com")
204+ >>> ssl.match_hostname(cert, "example.org")
205+ Traceback (most recent call last):
206+ File "<stdin>", line 1, in <module>
207+ File "/home/py3k/Lib/ssl.py", line 130, in match_hostname
208+ ssl.CertificateError: hostname 'example.org' doesn't match 'example.com'
209+
210+ .. versionadded :: 3.2
211+
167212.. function :: cert_time_to_seconds(timestring)
168213
169214 Returns a floating-point value containing a normal seconds-after-the-epoch
@@ -178,7 +223,6 @@ Functions, Constants, and Exceptions
178223 >>> import time
179224 >>> time.ctime(ssl.cert_time_to_seconds("May 9 00:00:00 2007 GMT"))
180225 'Wed May 9 00:00:00 2007'
181- >>>
182226
183227.. function :: get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None)
184228
@@ -201,6 +245,9 @@ Functions, Constants, and Exceptions
201245 Given a certificate as an ASCII PEM string, returns a DER-encoded sequence of
202246 bytes for that same certificate.
203247
248+ Constants
249+ ^^^^^^^^^
250+
204251.. data :: CERT_NONE
205252
206253 Possible value for :attr: `SSLContext.verify_mode `, or the ``cert_reqs ``
@@ -683,80 +730,67 @@ should use the following idiom::
683730Client-side operation
684731^^^^^^^^^^^^^^^^^^^^^
685732
686- This example connects to an SSL server, prints the server's address and
687- certificate, sends some bytes, and reads part of the response::
733+ This example connects to an SSL server and prints the server's certificate::
688734
689735 import socket, ssl, pprint
690736
691737 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
692-
693738 # require a certificate from the server
694739 ssl_sock = ssl.wrap_socket(s,
695740 ca_certs="/etc/ca_certs_file",
696741 cert_reqs=ssl.CERT_REQUIRED)
697-
698742 ssl_sock.connect(('www.verisign.com', 443))
699743
700- print(repr(ssl_sock.getpeername()))
701744 pprint.pprint(ssl_sock.getpeercert())
702- print(pprint.pformat(ssl_sock.getpeercert()))
703-
704- # Set a simple HTTP request -- use http.client in actual code.
705- ssl_sock.sendall(b"GET / HTTP/1.0\r\nHost: www.verisign.com\r\n\r\n")
706-
707- # Read a chunk of data. Will not necessarily
708- # read all the data returned by the server.
709- data = ssl_sock.recv()
710-
711745 # note that closing the SSLSocket will also close the underlying socket
712746 ssl_sock.close()
713747
714- As of September 6, 2007 , the certificate printed by this program looked like
748+ As of October 6, 2010 , the certificate printed by this program looks like
715749this::
716750
717- {'notAfter': 'May 8 23:59:59 2009 GMT',
718- 'subject': ((('serialNumber', '2497886'),),
719- (('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
720- (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
721- (('countryName', 'US'),),
722- (('postalCode', '94043'),),
723- (('stateOrProvinceName', 'California'),),
724- (('localityName', 'Mountain View'),),
725- (('streetAddress', '487 East Middlefield Road'),),
726- (('organizationName', 'VeriSign, Inc.'),),
727- (('organizationalUnitName',
728- 'Production Security Services'),),
729- (('organizationalUnitName',
730- 'Terms of use at www.verisign.com/rpa (c)06'),),
731- (('commonName', 'www.verisign.com'),))}
732-
733- which is a fairly poorly-formed ``subject `` field.
751+ {'notAfter': 'May 25 23:59:59 2012 GMT',
752+ 'subject': ((('1.3.6.1.4.1.311.60.2.1.3', 'US'),),
753+ (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),),
754+ (('businessCategory', 'V1.0, Clause 5.(b)'),),
755+ (('serialNumber', '2497886'),),
756+ (('countryName', 'US'),),
757+ (('postalCode', '94043'),),
758+ (('stateOrProvinceName', 'California'),),
759+ (('localityName', 'Mountain View'),),
760+ (('streetAddress', '487 East Middlefield Road'),),
761+ (('organizationName', 'VeriSign, Inc.'),),
762+ (('organizationalUnitName', ' Production Security Services'),),
763+ (('commonName', 'www.verisign.com'),))}
734764
735765This other example first creates an SSL context, instructs it to verify
736766certificates sent by peers, and feeds it a set of recognized certificate
737767authorities (CA)::
738768
739769 >>> context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
740- >>> context.verify_mode = ssl.CERT_OPTIONAL
770+ >>> context.verify_mode = ssl.CERT_REQUIRED
741771 >>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
742772
743773(it is assumed your operating system places a bundle of all CA certificates
744774in ``/etc/ssl/certs/ca-bundle.crt ``; if not, you'll get an error and have
745775to adjust the location)
746776
747- When you use the context to connect to a server, :const: `CERT_OPTIONAL `
777+ When you use the context to connect to a server, :const: `CERT_REQUIRED `
748778validates the server certificate: it ensures that the server certificate
749779was signed with one of the CA certificates, and checks the signature for
750780correctness::
751781
752782 >>> conn = context.wrap_socket(socket.socket(socket.AF_INET))
753783 >>> conn.connect(("linuxfr.org", 443))
754784
755- You should then fetch the certificate and check its fields for conformity.
756- Here, the ``commonName `` field in the ``subject `` matches the desired HTTPS
757- host ``linuxfr.org ``::
785+ You should then fetch the certificate and check its fields for conformity::
758786
759- >>> pprint.pprint(conn.getpeercert())
787+ >>> cert = conn.getpeercert()
788+ >>> ssl.match_hostname(cert, "linuxfr.org")
789+
790+ Visual inspection shows that the certificate does identify the desired service
791+ (that is, the HTTPS host ``linuxfr.org ``)::
792+
793+ >>> pprint.pprint(cert)
760794 {'notAfter': 'Jun 26 21:41:46 2011 GMT',
761795 'subject': ((('commonName', 'linuxfr.org'),),),
762796 'subjectAltName': (('DNS', 'linuxfr.org'), ('othername', '<unsupported>'))}
@@ -776,7 +810,6 @@ the server::
776810 b'',
777811 b'']
778812
779-
780813See the discussion of :ref: `ssl-security ` below.
781814
782815
@@ -842,12 +875,10 @@ peer, it can be insecure, especially in client mode where most of time you
842875would like to ensure the authenticity of the server you're talking to.
843876Therefore, when in client mode, it is highly recommended to use
844877:const: `CERT_REQUIRED `. However, it is in itself not sufficient; you also
845- have to check that the server certificate (obtained with
846- :meth: `SSLSocket.getpeercert `) matches the desired service. The exact way
847- of doing so depends on the higher-level protocol used; for example, with
848- HTTPS, you'll check that the host name in the URL matches either the
849- ``commonName `` field in the ``subjectName ``, or one of the ``DNS `` fields
850- in the ``subjectAltName ``.
878+ have to check that the server certificate, which can be obtained by calling
879+ :meth: `SSLSocket.getpeercert `, matches the desired service. For many
880+ protocols and applications, the service can be identified by the hostname;
881+ in this case, the :func: `match_hostname ` function can be used.
851882
852883In server mode, if you want to authenticate your clients using the SSL layer
853884(rather than using a higher-level authentication mechanism), you'll also have
0 commit comments