blob: 793ed496c77af4068520ca1fdfff7e4553c4eaad [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Wrapper module for _ssl, providing some additional facilities
2# implemented in Python. Written by Bill Janssen.
3
Guido van Rossum5b8b1552007-11-16 00:06:11 +00004"""This module provides some more Pythonic support for SSL.
Thomas Woutersed03b412007-08-28 21:37:11 +00005
6Object types:
7
Thomas Wouters1b7f8912007-09-19 03:06:30 +00008 SSLSocket -- subtype of socket.socket which does SSL over the socket
Thomas Woutersed03b412007-08-28 21:37:11 +00009
10Exceptions:
11
Thomas Wouters1b7f8912007-09-19 03:06:30 +000012 SSLError -- exception raised for I/O errors
Thomas Woutersed03b412007-08-28 21:37:11 +000013
14Functions:
15
16 cert_time_to_seconds -- convert time string used for certificate
17 notBefore and notAfter functions to integer
18 seconds past the Epoch (the time values
19 returned from time.time())
20
21 fetch_server_certificate (HOST, PORT) -- fetch the certificate provided
22 by the server running on HOST at port PORT. No
23 validation of the certificate is performed.
24
25Integer constants:
26
27SSL_ERROR_ZERO_RETURN
28SSL_ERROR_WANT_READ
29SSL_ERROR_WANT_WRITE
30SSL_ERROR_WANT_X509_LOOKUP
31SSL_ERROR_SYSCALL
32SSL_ERROR_SSL
33SSL_ERROR_WANT_CONNECT
34
35SSL_ERROR_EOF
36SSL_ERROR_INVALID_ERROR_CODE
37
38The following group define certificate requirements that one side is
39allowing/requiring from the other side:
40
41CERT_NONE - no certificates from the other side are required (or will
42 be looked at if provided)
43CERT_OPTIONAL - certificates are not required, but if provided will be
44 validated, and if validation fails, the connection will
45 also fail
46CERT_REQUIRED - certificates are required, and will be validated, and
47 if validation fails, the connection will also fail
48
49The following constants identify various SSL protocol variants:
50
51PROTOCOL_SSLv2
52PROTOCOL_SSLv3
53PROTOCOL_SSLv23
Christian Heimes598894f2016-09-05 23:19:05 +020054PROTOCOL_TLS
Christian Heimes5fe668c2016-09-12 00:01:11 +020055PROTOCOL_TLS_CLIENT
56PROTOCOL_TLS_SERVER
Thomas Woutersed03b412007-08-28 21:37:11 +000057PROTOCOL_TLSv1
Antoine Pitrou2463e5f2013-03-28 22:24:43 +010058PROTOCOL_TLSv1_1
59PROTOCOL_TLSv1_2
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010060
61The following constants identify various SSL alert message descriptions as per
62http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6
63
64ALERT_DESCRIPTION_CLOSE_NOTIFY
65ALERT_DESCRIPTION_UNEXPECTED_MESSAGE
66ALERT_DESCRIPTION_BAD_RECORD_MAC
67ALERT_DESCRIPTION_RECORD_OVERFLOW
68ALERT_DESCRIPTION_DECOMPRESSION_FAILURE
69ALERT_DESCRIPTION_HANDSHAKE_FAILURE
70ALERT_DESCRIPTION_BAD_CERTIFICATE
71ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE
72ALERT_DESCRIPTION_CERTIFICATE_REVOKED
73ALERT_DESCRIPTION_CERTIFICATE_EXPIRED
74ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN
75ALERT_DESCRIPTION_ILLEGAL_PARAMETER
76ALERT_DESCRIPTION_UNKNOWN_CA
77ALERT_DESCRIPTION_ACCESS_DENIED
78ALERT_DESCRIPTION_DECODE_ERROR
79ALERT_DESCRIPTION_DECRYPT_ERROR
80ALERT_DESCRIPTION_PROTOCOL_VERSION
81ALERT_DESCRIPTION_INSUFFICIENT_SECURITY
82ALERT_DESCRIPTION_INTERNAL_ERROR
83ALERT_DESCRIPTION_USER_CANCELLED
84ALERT_DESCRIPTION_NO_RENEGOTIATION
85ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION
86ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE
87ALERT_DESCRIPTION_UNRECOGNIZED_NAME
88ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE
89ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE
90ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY
Thomas Woutersed03b412007-08-28 21:37:11 +000091"""
92
Christian Heimes46bebee2013-06-09 19:03:31 +020093import sys
Christian Heimes6d7ad132013-06-09 18:02:55 +020094import os
Christian Heimesa6bc95a2013-11-17 19:59:14 +010095from collections import namedtuple
Christian Heimes3aeacad2016-09-10 00:19:35 +020096from enum import Enum as _Enum, IntEnum as _IntEnum, IntFlag as _IntFlag
Thomas Woutersed03b412007-08-28 21:37:11 +000097
98import _ssl # if we can't import it, let the error propagate
Thomas Wouters1b7f8912007-09-19 03:06:30 +000099
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000100from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
Christian Heimes99a65702016-09-10 23:44:53 +0200101from _ssl import _SSLContext, MemoryBIO, SSLSession
Antoine Pitrou41032a62011-10-27 23:56:55 +0200102from _ssl import (
103 SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
Christian Heimesb3ad0e52017-09-08 12:00:19 -0700104 SSLSyscallError, SSLEOFError, SSLCertVerificationError
Antoine Pitrou41032a62011-10-27 23:56:55 +0200105 )
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100106from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
Victor Stinnerbeeb5122014-11-28 13:28:25 +0100107from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes
108try:
109 from _ssl import RAND_egd
110except ImportError:
111 # LibreSSL does not provide RAND_egd
112 pass
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100113
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100114
Christian Heimes698dde12018-02-27 11:54:43 +0100115from _ssl import (
116 HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1,
117 HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3
118)
119from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION
Antoine Pitroub9ac25d2011-07-08 18:47:06 +0200120
Christian Heimes3aeacad2016-09-10 00:19:35 +0200121
orlnub1230fb9fad2018-09-12 20:28:53 +0300122_IntEnum._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200123 '_SSLMethod', __name__,
124 lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23',
125 source=_ssl)
126
orlnub1230fb9fad2018-09-12 20:28:53 +0300127_IntFlag._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200128 'Options', __name__,
129 lambda name: name.startswith('OP_'),
130 source=_ssl)
131
orlnub1230fb9fad2018-09-12 20:28:53 +0300132_IntEnum._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200133 'AlertDescription', __name__,
134 lambda name: name.startswith('ALERT_DESCRIPTION_'),
135 source=_ssl)
136
orlnub1230fb9fad2018-09-12 20:28:53 +0300137_IntEnum._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200138 'SSLErrorNumber', __name__,
139 lambda name: name.startswith('SSL_ERROR_'),
140 source=_ssl)
141
orlnub1230fb9fad2018-09-12 20:28:53 +0300142_IntFlag._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200143 'VerifyFlags', __name__,
144 lambda name: name.startswith('VERIFY_'),
145 source=_ssl)
146
orlnub1230fb9fad2018-09-12 20:28:53 +0300147_IntEnum._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200148 'VerifyMode', __name__,
149 lambda name: name.startswith('CERT_'),
150 source=_ssl)
151
Christian Heimes598894f2016-09-05 23:19:05 +0200152PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS
Antoine Pitrou172f0252014-04-18 20:33:08 +0200153_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()}
154
Christian Heimes3aeacad2016-09-10 00:19:35 +0200155_SSLv2_IF_EXISTS = getattr(_SSLMethod, 'PROTOCOL_SSLv2', None)
156
Antoine Pitrou2463e5f2013-03-28 22:24:43 +0100157
Christian Heimes698dde12018-02-27 11:54:43 +0100158class TLSVersion(_IntEnum):
159 MINIMUM_SUPPORTED = _ssl.PROTO_MINIMUM_SUPPORTED
160 SSLv3 = _ssl.PROTO_SSLv3
161 TLSv1 = _ssl.PROTO_TLSv1
162 TLSv1_1 = _ssl.PROTO_TLSv1_1
163 TLSv1_2 = _ssl.PROTO_TLSv1_2
164 TLSv1_3 = _ssl.PROTO_TLSv1_3
165 MAXIMUM_SUPPORTED = _ssl.PROTO_MAXIMUM_SUPPORTED
166
167
Christian Heimes46bebee2013-06-09 19:03:31 +0200168if sys.platform == "win32":
Christian Heimes44109d72013-11-22 01:51:30 +0100169 from _ssl import enum_certificates, enum_crls
Christian Heimes46bebee2013-06-09 19:03:31 +0200170
Antoine Pitrou15399c32011-04-28 19:23:55 +0200171from socket import socket, AF_INET, SOCK_STREAM, create_connection
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100172from socket import SOL_SOCKET, SO_TYPE
Christian Heimesaef12832018-02-24 14:35:56 +0100173import socket as _socket
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000174import base64 # for DER-to-PEM translation
Antoine Pitroude8cf322010-04-26 17:29:05 +0000175import errno
Steve Dower33bc4a22016-05-26 12:18:12 -0700176import warnings
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000177
Andrew Svetlov0832af62012-12-18 23:10:48 +0200178
179socket_error = OSError # keep that public name in module namespace
180
Christian Heimes141c5e82018-02-24 21:10:57 +0100181CHANNEL_BINDING_TYPES = ['tls-unique']
Thomas Woutersed03b412007-08-28 21:37:11 +0000182
Christian Heimes61d478c2018-01-27 15:51:38 +0100183HAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT')
184
Christian Heimes03d13c02016-09-06 20:06:47 +0200185
Christian Heimes892d66e2018-01-29 14:10:18 +0100186_RESTRICTED_SERVER_CIPHERS = _DEFAULT_CIPHERS
Christian Heimes4c05b472013-11-23 15:58:30 +0100187
Christian Heimes61d478c2018-01-27 15:51:38 +0100188CertificateError = SSLCertVerificationError
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000189
190
Mandeep Singhede2ac92017-11-27 04:01:27 +0530191def _dnsname_match(dn, hostname):
Georg Brandl72c98d32013-10-27 07:16:53 +0100192 """Matching according to RFC 6125, section 6.4.3
193
Christian Heimesaef12832018-02-24 14:35:56 +0100194 - Hostnames are compared lower case.
195 - For IDNA, both dn and hostname must be encoded as IDN A-label (ACE).
196 - Partial wildcards like 'www*.example.org', multiple wildcards, sole
197 wildcard or wildcards in labels other then the left-most label are not
198 supported and a CertificateError is raised.
199 - A wildcard must match at least one character.
Georg Brandl72c98d32013-10-27 07:16:53 +0100200 """
Georg Brandl72c98d32013-10-27 07:16:53 +0100201 if not dn:
202 return False
203
Christian Heimesaef12832018-02-24 14:35:56 +0100204 wildcards = dn.count('*')
Georg Brandl72c98d32013-10-27 07:16:53 +0100205 # speed up common case w/o wildcards
206 if not wildcards:
207 return dn.lower() == hostname.lower()
208
Christian Heimesaef12832018-02-24 14:35:56 +0100209 if wildcards > 1:
210 raise CertificateError(
211 "too many wildcards in certificate DNS name: {!r}.".format(dn))
Georg Brandl72c98d32013-10-27 07:16:53 +0100212
Christian Heimesaef12832018-02-24 14:35:56 +0100213 dn_leftmost, sep, dn_remainder = dn.partition('.')
Georg Brandl72c98d32013-10-27 07:16:53 +0100214
Christian Heimesaef12832018-02-24 14:35:56 +0100215 if '*' in dn_remainder:
216 # Only match wildcard in leftmost segment.
217 raise CertificateError(
218 "wildcard can only be present in the leftmost label: "
219 "{!r}.".format(dn))
220
221 if not sep:
222 # no right side
223 raise CertificateError(
224 "sole wildcard without additional labels are not support: "
225 "{!r}.".format(dn))
226
227 if dn_leftmost != '*':
228 # no partial wildcard matching
229 raise CertificateError(
230 "partial wildcards in leftmost label are not supported: "
231 "{!r}.".format(dn))
232
233 hostname_leftmost, sep, hostname_remainder = hostname.partition('.')
234 if not hostname_leftmost or not sep:
235 # wildcard must match at least one char
236 return False
237 return dn_remainder.lower() == hostname_remainder.lower()
238
239
240def _inet_paton(ipname):
241 """Try to convert an IP address to packed binary form
242
243 Supports IPv4 addresses on all platforms and IPv6 on platforms with IPv6
244 support.
245 """
246 # inet_aton() also accepts strings like '1'
247 if ipname.count('.') == 3:
248 try:
249 return _socket.inet_aton(ipname)
250 except OSError:
251 pass
252
253 try:
254 return _socket.inet_pton(_socket.AF_INET6, ipname)
255 except OSError:
256 raise ValueError("{!r} is neither an IPv4 nor an IP6 "
257 "address.".format(ipname))
258 except AttributeError:
259 # AF_INET6 not available
260 pass
261
262 raise ValueError("{!r} is not an IPv4 address.".format(ipname))
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000263
264
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100265def _ipaddress_match(ipname, host_ip):
266 """Exact matching of IP addresses.
267
268 RFC 6125 explicitly doesn't define an algorithm for this
269 (section 1.7.2 - "Out of Scope").
270 """
271 # OpenSSL may add a trailing newline to a subjectAltName's IP address
Christian Heimesaef12832018-02-24 14:35:56 +0100272 ip = _inet_paton(ipname.rstrip())
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100273 return ip == host_ip
274
275
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000276def match_hostname(cert, hostname):
277 """Verify that *cert* (in decoded format as returned by
Georg Brandl72c98d32013-10-27 07:16:53 +0100278 SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
Christian Heimesaef12832018-02-24 14:35:56 +0100279 rules are followed.
280
281 The function matches IP addresses rather than dNSNames if hostname is a
282 valid ipaddress string. IPv4 addresses are supported on all platforms.
283 IPv6 addresses are supported on platforms with IPv6 support (AF_INET6
284 and inet_pton).
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000285
286 CertificateError is raised on failure. On success, the function
287 returns nothing.
288 """
289 if not cert:
Christian Heimes1aa9a752013-12-02 02:41:19 +0100290 raise ValueError("empty or no certificate, match_hostname needs a "
291 "SSL socket or SSL context with either "
292 "CERT_OPTIONAL or CERT_REQUIRED")
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100293 try:
Christian Heimesaef12832018-02-24 14:35:56 +0100294 host_ip = _inet_paton(hostname)
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100295 except ValueError:
296 # Not an IP address (common case)
297 host_ip = None
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000298 dnsnames = []
299 san = cert.get('subjectAltName', ())
300 for key, value in san:
301 if key == 'DNS':
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100302 if host_ip is None and _dnsname_match(value, hostname):
303 return
304 dnsnames.append(value)
305 elif key == 'IP Address':
306 if host_ip is not None and _ipaddress_match(value, host_ip):
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000307 return
308 dnsnames.append(value)
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200309 if not dnsnames:
310 # The subject is only checked when there is no dNSName entry
311 # in subjectAltName
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000312 for sub in cert.get('subject', ()):
313 for key, value in sub:
314 # XXX according to RFC 2818, the most specific Common Name
315 # must be used.
316 if key == 'commonName':
Georg Brandl72c98d32013-10-27 07:16:53 +0100317 if _dnsname_match(value, hostname):
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000318 return
319 dnsnames.append(value)
320 if len(dnsnames) > 1:
321 raise CertificateError("hostname %r "
322 "doesn't match either of %s"
323 % (hostname, ', '.join(map(repr, dnsnames))))
324 elif len(dnsnames) == 1:
325 raise CertificateError("hostname %r "
326 "doesn't match %r"
327 % (hostname, dnsnames[0]))
328 else:
329 raise CertificateError("no appropriate commonName or "
330 "subjectAltName fields were found")
331
332
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100333DefaultVerifyPaths = namedtuple("DefaultVerifyPaths",
Christian Heimes6d7ad132013-06-09 18:02:55 +0200334 "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env "
335 "openssl_capath")
336
337def get_default_verify_paths():
338 """Return paths to default cafile and capath.
339 """
340 parts = _ssl.get_default_verify_paths()
341
342 # environment vars shadow paths
343 cafile = os.environ.get(parts[0], parts[1])
344 capath = os.environ.get(parts[2], parts[3])
345
346 return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None,
347 capath if os.path.isdir(capath) else None,
348 *parts)
349
350
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100351class _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")):
352 """ASN.1 object identifier lookup
353 """
354 __slots__ = ()
355
356 def __new__(cls, oid):
357 return super().__new__(cls, *_txt2obj(oid, name=False))
358
359 @classmethod
360 def fromnid(cls, nid):
361 """Create _ASN1Object from OpenSSL numeric ID
362 """
363 return super().__new__(cls, *_nid2obj(nid))
364
365 @classmethod
366 def fromname(cls, name):
367 """Create _ASN1Object from short name, long name or OID
368 """
369 return super().__new__(cls, *_txt2obj(name, name=True))
370
371
Christian Heimes72d28502013-11-23 13:56:58 +0100372class Purpose(_ASN1Object, _Enum):
373 """SSLContext purpose flags with X509v3 Extended Key Usage objects
374 """
375 SERVER_AUTH = '1.3.6.1.5.5.7.3.1'
376 CLIENT_AUTH = '1.3.6.1.5.5.7.3.2'
377
378
Antoine Pitrou152efa22010-05-16 18:19:27 +0000379class SSLContext(_SSLContext):
380 """An SSLContext holds various SSL-related configuration options and
381 data, such as certificates and possibly a private key."""
Christian Heimes72d28502013-11-23 13:56:58 +0100382 _windows_cert_stores = ("CA", "ROOT")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000383
Christian Heimes4df60f12017-09-15 20:26:05 +0200384 sslsocket_class = None # SSLSocket is assigned later.
385 sslobject_class = None # SSLObject is assigned later.
386
Christian Heimes598894f2016-09-05 23:19:05 +0200387 def __new__(cls, protocol=PROTOCOL_TLS, *args, **kwargs):
Antoine Pitrou8f85f902012-01-03 22:46:48 +0100388 self = _SSLContext.__new__(cls, protocol)
Antoine Pitrou8f85f902012-01-03 22:46:48 +0100389 return self
Antoine Pitrou152efa22010-05-16 18:19:27 +0000390
Christian Heimes11a14932018-02-24 02:35:08 +0100391 def _encode_hostname(self, hostname):
392 if hostname is None:
393 return None
394 elif isinstance(hostname, str):
395 return hostname.encode('idna').decode('ascii')
396 else:
397 return hostname.decode('ascii')
Antoine Pitrou152efa22010-05-16 18:19:27 +0000398
399 def wrap_socket(self, sock, server_side=False,
400 do_handshake_on_connect=True,
Antoine Pitroud5323212010-10-22 18:19:07 +0000401 suppress_ragged_eofs=True,
Christian Heimes99a65702016-09-10 23:44:53 +0200402 server_hostname=None, session=None):
Christian Heimes11a14932018-02-24 02:35:08 +0100403 # SSLSocket class handles server_hostname encoding before it calls
404 # ctx._wrap_socket()
Christian Heimes9d50ab52018-02-27 10:17:30 +0100405 return self.sslsocket_class._create(
Christian Heimes4df60f12017-09-15 20:26:05 +0200406 sock=sock,
407 server_side=server_side,
408 do_handshake_on_connect=do_handshake_on_connect,
409 suppress_ragged_eofs=suppress_ragged_eofs,
410 server_hostname=server_hostname,
Christian Heimes9d50ab52018-02-27 10:17:30 +0100411 context=self,
412 session=session
Christian Heimes4df60f12017-09-15 20:26:05 +0200413 )
Antoine Pitrou152efa22010-05-16 18:19:27 +0000414
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200415 def wrap_bio(self, incoming, outgoing, server_side=False,
Christian Heimes99a65702016-09-10 23:44:53 +0200416 server_hostname=None, session=None):
Christian Heimes11a14932018-02-24 02:35:08 +0100417 # Need to encode server_hostname here because _wrap_bio() can only
418 # handle ASCII str.
Christian Heimes9d50ab52018-02-27 10:17:30 +0100419 return self.sslobject_class._create(
Christian Heimes11a14932018-02-24 02:35:08 +0100420 incoming, outgoing, server_side=server_side,
Christian Heimes141c5e82018-02-24 21:10:57 +0100421 server_hostname=self._encode_hostname(server_hostname),
Christian Heimes9d50ab52018-02-27 10:17:30 +0100422 session=session, context=self,
Christian Heimes11a14932018-02-24 02:35:08 +0100423 )
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200424
Antoine Pitroud5d17eb2012-03-22 00:23:03 +0100425 def set_npn_protocols(self, npn_protocols):
426 protos = bytearray()
427 for protocol in npn_protocols:
428 b = bytes(protocol, 'ascii')
429 if len(b) == 0 or len(b) > 255:
430 raise SSLError('NPN protocols must be 1 to 255 in length')
431 protos.append(len(b))
432 protos.extend(b)
433
434 self._set_npn_protocols(protos)
435
Christian Heimes11a14932018-02-24 02:35:08 +0100436 def set_servername_callback(self, server_name_callback):
437 if server_name_callback is None:
438 self.sni_callback = None
439 else:
440 if not callable(server_name_callback):
441 raise TypeError("not a callable object")
442
443 def shim_cb(sslobj, servername, sslctx):
444 servername = self._encode_hostname(servername)
445 return server_name_callback(sslobj, servername, sslctx)
446
447 self.sni_callback = shim_cb
448
Benjamin Petersoncca27322015-01-23 16:35:37 -0500449 def set_alpn_protocols(self, alpn_protocols):
450 protos = bytearray()
451 for protocol in alpn_protocols:
452 b = bytes(protocol, 'ascii')
453 if len(b) == 0 or len(b) > 255:
454 raise SSLError('ALPN protocols must be 1 to 255 in length')
455 protos.append(len(b))
456 protos.extend(b)
457
458 self._set_alpn_protocols(protos)
459
Christian Heimes72d28502013-11-23 13:56:58 +0100460 def _load_windows_store_certs(self, storename, purpose):
461 certs = bytearray()
Steve Dower33bc4a22016-05-26 12:18:12 -0700462 try:
463 for cert, encoding, trust in enum_certificates(storename):
464 # CA certs are never PKCS#7 encoded
465 if encoding == "x509_asn":
466 if trust is True or purpose.oid in trust:
467 certs.extend(cert)
468 except PermissionError:
469 warnings.warn("unable to enumerate Windows certificate store")
Steve Dower8dd7aeb2016-03-17 15:02:39 -0700470 if certs:
471 self.load_verify_locations(cadata=certs)
Christian Heimes72d28502013-11-23 13:56:58 +0100472 return certs
473
474 def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
475 if not isinstance(purpose, _ASN1Object):
476 raise TypeError(purpose)
477 if sys.platform == "win32":
478 for storename in self._windows_cert_stores:
479 self._load_windows_store_certs(storename, purpose)
Benjamin Peterson5915b0f2014-10-03 17:27:05 -0400480 self.set_default_verify_paths()
Christian Heimes72d28502013-11-23 13:56:58 +0100481
Christian Heimes698dde12018-02-27 11:54:43 +0100482 if hasattr(_SSLContext, 'minimum_version'):
483 @property
484 def minimum_version(self):
485 return TLSVersion(super().minimum_version)
486
487 @minimum_version.setter
488 def minimum_version(self, value):
489 if value == TLSVersion.SSLv3:
490 self.options &= ~Options.OP_NO_SSLv3
491 super(SSLContext, SSLContext).minimum_version.__set__(self, value)
492
493 @property
494 def maximum_version(self):
495 return TLSVersion(super().maximum_version)
496
497 @maximum_version.setter
498 def maximum_version(self, value):
499 super(SSLContext, SSLContext).maximum_version.__set__(self, value)
500
Christian Heimes3aeacad2016-09-10 00:19:35 +0200501 @property
502 def options(self):
503 return Options(super().options)
504
505 @options.setter
506 def options(self, value):
507 super(SSLContext, SSLContext).options.__set__(self, value)
508
Christian Heimes61d478c2018-01-27 15:51:38 +0100509 if hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT'):
510 @property
511 def hostname_checks_common_name(self):
512 ncs = self._host_flags & _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
513 return ncs != _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
514
515 @hostname_checks_common_name.setter
516 def hostname_checks_common_name(self, value):
517 if value:
518 self._host_flags &= ~_ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
519 else:
520 self._host_flags |= _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
521 else:
522 @property
523 def hostname_checks_common_name(self):
524 return True
525
Christian Heimes3aeacad2016-09-10 00:19:35 +0200526 @property
Christian Heimes11a14932018-02-24 02:35:08 +0100527 def protocol(self):
528 return _SSLMethod(super().protocol)
529
530 @property
Christian Heimes3aeacad2016-09-10 00:19:35 +0200531 def verify_flags(self):
532 return VerifyFlags(super().verify_flags)
533
534 @verify_flags.setter
535 def verify_flags(self, value):
536 super(SSLContext, SSLContext).verify_flags.__set__(self, value)
537
538 @property
539 def verify_mode(self):
540 value = super().verify_mode
541 try:
542 return VerifyMode(value)
543 except ValueError:
544 return value
545
546 @verify_mode.setter
547 def verify_mode(self, value):
548 super(SSLContext, SSLContext).verify_mode.__set__(self, value)
549
Antoine Pitrou152efa22010-05-16 18:19:27 +0000550
Christian Heimes4c05b472013-11-23 15:58:30 +0100551def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
552 capath=None, cadata=None):
553 """Create a SSLContext object with default settings.
554
555 NOTE: The protocol and settings may change anytime without prior
556 deprecation. The values represent a fair balance between maximum
557 compatibility and security.
558 """
559 if not isinstance(purpose, _ASN1Object):
560 raise TypeError(purpose)
Donald Stufft6a2ba942014-03-23 19:05:28 -0400561
Christian Heimes358cfd42016-09-10 22:43:48 +0200562 # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
563 # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
564 # by default.
Christian Heimes598894f2016-09-05 23:19:05 +0200565 context = SSLContext(PROTOCOL_TLS)
Donald Stufft6a2ba942014-03-23 19:05:28 -0400566
Christian Heimes4c05b472013-11-23 15:58:30 +0100567 if purpose == Purpose.SERVER_AUTH:
Donald Stufft6a2ba942014-03-23 19:05:28 -0400568 # verify certs and host name in client mode
Christian Heimes4c05b472013-11-23 15:58:30 +0100569 context.verify_mode = CERT_REQUIRED
Christian Heimes1aa9a752013-12-02 02:41:19 +0100570 context.check_hostname = True
Donald Stufft6a2ba942014-03-23 19:05:28 -0400571
Christian Heimes4c05b472013-11-23 15:58:30 +0100572 if cafile or capath or cadata:
573 context.load_verify_locations(cafile, capath, cadata)
574 elif context.verify_mode != CERT_NONE:
575 # no explicit cafile, capath or cadata but the verify mode is
576 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
577 # root CA certificates for the given purpose. This may fail silently.
578 context.load_default_certs(purpose)
579 return context
580
Christian Heimesa170fa12017-09-15 20:27:30 +0200581def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=CERT_NONE,
Christian Heimesa02c69a2013-12-02 20:59:28 +0100582 check_hostname=False, purpose=Purpose.SERVER_AUTH,
Christian Heimes67986f92013-11-23 22:43:47 +0100583 certfile=None, keyfile=None,
584 cafile=None, capath=None, cadata=None):
585 """Create a SSLContext object for Python stdlib modules
586
587 All Python stdlib modules shall use this function to create SSLContext
588 objects in order to keep common settings in one place. The configuration
589 is less restrict than create_default_context()'s to increase backward
590 compatibility.
591 """
592 if not isinstance(purpose, _ASN1Object):
593 raise TypeError(purpose)
594
Christian Heimes358cfd42016-09-10 22:43:48 +0200595 # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
596 # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
597 # by default.
Christian Heimes67986f92013-11-23 22:43:47 +0100598 context = SSLContext(protocol)
Christian Heimes67986f92013-11-23 22:43:47 +0100599
Christian Heimesa170fa12017-09-15 20:27:30 +0200600 if not check_hostname:
601 context.check_hostname = False
Christian Heimes67986f92013-11-23 22:43:47 +0100602 if cert_reqs is not None:
603 context.verify_mode = cert_reqs
Christian Heimesa170fa12017-09-15 20:27:30 +0200604 if check_hostname:
605 context.check_hostname = True
Christian Heimes67986f92013-11-23 22:43:47 +0100606
607 if keyfile and not certfile:
608 raise ValueError("certfile must be specified")
609 if certfile or keyfile:
610 context.load_cert_chain(certfile, keyfile)
611
612 # load CA root certs
613 if cafile or capath or cadata:
614 context.load_verify_locations(cafile, capath, cadata)
615 elif context.verify_mode != CERT_NONE:
616 # no explicit cafile, capath or cadata but the verify mode is
617 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
618 # root CA certificates for the given purpose. This may fail silently.
619 context.load_default_certs(purpose)
620
621 return context
622
Benjamin Peterson4ffb0752014-11-03 14:29:33 -0500623# Used by http.client if no context is explicitly passed.
624_create_default_https_context = create_default_context
625
626
627# Backwards compatibility alias, even though it's not a public name.
628_create_stdlib_context = _create_unverified_context
629
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200630
631class SSLObject:
632 """This class implements an interface on top of a low-level SSL object as
633 implemented by OpenSSL. This object captures the state of an SSL connection
634 but does not provide any network IO itself. IO needs to be performed
635 through separate "BIO" objects which are OpenSSL's IO abstraction layer.
636
637 This class does not have a public constructor. Instances are returned by
638 ``SSLContext.wrap_bio``. This class is typically used by framework authors
639 that want to implement asynchronous IO for SSL through memory buffers.
640
641 When compared to ``SSLSocket``, this object lacks the following features:
642
Matt Eatonfc7d1b32018-10-05 02:00:45 -0500643 * Any form of network IO, including methods such as ``recv`` and ``send``.
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200644 * The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery.
645 """
Christian Heimes9d50ab52018-02-27 10:17:30 +0100646 def __init__(self, *args, **kwargs):
647 raise TypeError(
648 f"{self.__class__.__name__} does not have a public "
649 f"constructor. Instances are returned by SSLContext.wrap_bio()."
650 )
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200651
Christian Heimes9d50ab52018-02-27 10:17:30 +0100652 @classmethod
653 def _create(cls, incoming, outgoing, server_side=False,
654 server_hostname=None, session=None, context=None):
655 self = cls.__new__(cls)
656 sslobj = context._wrap_bio(
Christian Heimes141c5e82018-02-24 21:10:57 +0100657 incoming, outgoing, server_side=server_side,
658 server_hostname=server_hostname,
659 owner=self, session=session
660 )
Christian Heimes9d50ab52018-02-27 10:17:30 +0100661 self._sslobj = sslobj
662 return self
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200663
664 @property
665 def context(self):
666 """The SSLContext that is currently in use."""
667 return self._sslobj.context
668
669 @context.setter
670 def context(self, ctx):
671 self._sslobj.context = ctx
672
673 @property
Christian Heimes99a65702016-09-10 23:44:53 +0200674 def session(self):
675 """The SSLSession for client socket."""
676 return self._sslobj.session
677
678 @session.setter
679 def session(self, session):
680 self._sslobj.session = session
681
682 @property
683 def session_reused(self):
684 """Was the client session reused during handshake"""
685 return self._sslobj.session_reused
686
687 @property
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200688 def server_side(self):
689 """Whether this is a server-side socket."""
690 return self._sslobj.server_side
691
692 @property
693 def server_hostname(self):
694 """The currently set server hostname (for SNI), or ``None`` if no
695 server hostame is set."""
696 return self._sslobj.server_hostname
697
Martin Panterf6b1d662016-03-28 00:22:09 +0000698 def read(self, len=1024, buffer=None):
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200699 """Read up to 'len' bytes from the SSL object and return them.
700
701 If 'buffer' is provided, read into this buffer and return the number of
702 bytes read.
703 """
704 if buffer is not None:
705 v = self._sslobj.read(len, buffer)
706 else:
Martin Panterf6b1d662016-03-28 00:22:09 +0000707 v = self._sslobj.read(len)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200708 return v
709
710 def write(self, data):
711 """Write 'data' to the SSL object and return the number of bytes
712 written.
713
714 The 'data' argument must support the buffer interface.
715 """
716 return self._sslobj.write(data)
717
718 def getpeercert(self, binary_form=False):
719 """Returns a formatted version of the data in the certificate provided
720 by the other end of the SSL channel.
721
722 Return None if no certificate was provided, {} if a certificate was
723 provided, but not validated.
724 """
Christian Heimes141c5e82018-02-24 21:10:57 +0100725 return self._sslobj.getpeercert(binary_form)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200726
727 def selected_npn_protocol(self):
728 """Return the currently selected NPN protocol as a string, or ``None``
729 if a next protocol was not negotiated or if NPN is not supported by one
730 of the peers."""
731 if _ssl.HAS_NPN:
732 return self._sslobj.selected_npn_protocol()
733
Benjamin Petersoncca27322015-01-23 16:35:37 -0500734 def selected_alpn_protocol(self):
735 """Return the currently selected ALPN protocol as a string, or ``None``
736 if a next protocol was not negotiated or if ALPN is not supported by one
737 of the peers."""
738 if _ssl.HAS_ALPN:
739 return self._sslobj.selected_alpn_protocol()
740
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200741 def cipher(self):
742 """Return the currently selected cipher as a 3-tuple ``(name,
743 ssl_version, secret_bits)``."""
744 return self._sslobj.cipher()
745
Benjamin Peterson4cb17812015-01-07 11:14:26 -0600746 def shared_ciphers(self):
Benjamin Petersonc114e7d2015-01-11 15:22:07 -0500747 """Return a list of ciphers shared by the client during the handshake or
748 None if this is not a valid server connection.
Benjamin Peterson5318c7a2015-01-07 11:26:50 -0600749 """
Benjamin Peterson4cb17812015-01-07 11:14:26 -0600750 return self._sslobj.shared_ciphers()
751
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200752 def compression(self):
753 """Return the current compression algorithm in use, or ``None`` if
754 compression was not negotiated or not supported by one of the peers."""
755 return self._sslobj.compression()
756
757 def pending(self):
758 """Return the number of bytes that can be read immediately."""
759 return self._sslobj.pending()
760
Antoine Pitrou3cb93792014-10-06 00:21:09 +0200761 def do_handshake(self):
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200762 """Start the SSL/TLS handshake."""
763 self._sslobj.do_handshake()
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200764
765 def unwrap(self):
766 """Start the SSL shutdown handshake."""
767 return self._sslobj.shutdown()
768
769 def get_channel_binding(self, cb_type="tls-unique"):
770 """Get channel binding data for current connection. Raise ValueError
771 if the requested `cb_type` is not supported. Return bytes of the data
772 or None if the data is not available (e.g. before the handshake)."""
Christian Heimes141c5e82018-02-24 21:10:57 +0100773 return self._sslobj.get_channel_binding(cb_type)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200774
775 def version(self):
776 """Return a string identifying the protocol version used by the
777 current SSL channel. """
778 return self._sslobj.version()
779
Christian Heimes9fb051f2018-09-23 08:32:31 +0200780 def verify_client_post_handshake(self):
781 return self._sslobj.verify_client_post_handshake()
782
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200783
Christian Heimes80ed3532019-05-17 13:08:14 +0200784def _sslcopydoc(func):
785 """Copy docstring from SSLObject to SSLSocket"""
786 func.__doc__ = getattr(SSLObject, func.__name__).__doc__
787 return func
788
789
Antoine Pitrou152efa22010-05-16 18:19:27 +0000790class SSLSocket(socket):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000791 """This class implements a subtype of socket.socket that wraps
792 the underlying OS socket in an SSL context when necessary, and
Christian Heimes9d50ab52018-02-27 10:17:30 +0100793 provides read and write methods over that channel. """
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000794
Christian Heimes9d50ab52018-02-27 10:17:30 +0100795 def __init__(self, *args, **kwargs):
796 raise TypeError(
797 f"{self.__class__.__name__} does not have a public "
798 f"constructor. Instances are returned by "
799 f"SSLContext.wrap_socket()."
800 )
Bill Janssen6e027db2007-11-15 22:23:56 +0000801
Christian Heimes9d50ab52018-02-27 10:17:30 +0100802 @classmethod
803 def _create(cls, sock, server_side=False, do_handshake_on_connect=True,
804 suppress_ragged_eofs=True, server_hostname=None,
805 context=None, session=None):
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100806 if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
807 raise NotImplementedError("only stream sockets are supported")
Christian Heimes99a65702016-09-10 23:44:53 +0200808 if server_side:
809 if server_hostname:
810 raise ValueError("server_hostname can only be specified "
811 "in client mode")
Christian Heimes9d50ab52018-02-27 10:17:30 +0100812 if session is not None:
Christian Heimes99a65702016-09-10 23:44:53 +0200813 raise ValueError("session can only be specified in "
814 "client mode")
Christian Heimes9d50ab52018-02-27 10:17:30 +0100815 if context.check_hostname and not server_hostname:
Benjamin Peterson7243b572014-11-23 17:04:34 -0600816 raise ValueError("check_hostname requires server_hostname")
Christian Heimes9d50ab52018-02-27 10:17:30 +0100817
818 kwargs = dict(
819 family=sock.family, type=sock.type, proto=sock.proto,
820 fileno=sock.fileno()
821 )
822 self = cls.__new__(cls, **kwargs)
823 super(SSLSocket, self).__init__(**kwargs)
824 self.settimeout(sock.gettimeout())
825 sock.detach()
826
827 self._context = context
828 self._session = session
829 self._closed = False
830 self._sslobj = None
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000831 self.server_side = server_side
Christian Heimes9d50ab52018-02-27 10:17:30 +0100832 self.server_hostname = context._encode_hostname(server_hostname)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000833 self.do_handshake_on_connect = do_handshake_on_connect
834 self.suppress_ragged_eofs = suppress_ragged_eofs
Bill Janssen6e027db2007-11-15 22:23:56 +0000835
Antoine Pitrou242db722013-05-01 20:52:07 +0200836 # See if we are connected
837 try:
838 self.getpeername()
839 except OSError as e:
840 if e.errno != errno.ENOTCONN:
841 raise
842 connected = False
843 else:
844 connected = True
845
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000846 self._connected = connected
Antoine Pitroufa2b9382010-04-26 22:17:47 +0000847 if connected:
848 # create the SSL object
Bill Janssen6e027db2007-11-15 22:23:56 +0000849 try:
Christian Heimes141c5e82018-02-24 21:10:57 +0100850 self._sslobj = self._context._wrap_socket(
851 self, server_side, self.server_hostname,
852 owner=self, session=self._session,
853 )
Bill Janssen6e027db2007-11-15 22:23:56 +0000854 if do_handshake_on_connect:
Bill Janssen48dc27c2007-12-05 03:38:10 +0000855 timeout = self.gettimeout()
856 if timeout == 0.0:
857 # non-blocking
858 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
Bill Janssen6e027db2007-11-15 22:23:56 +0000859 self.do_handshake()
Christian Heimes1aa9a752013-12-02 02:41:19 +0100860 except (OSError, ValueError):
Bill Janssen6e027db2007-11-15 22:23:56 +0000861 self.close()
Christian Heimes1aa9a752013-12-02 02:41:19 +0100862 raise
Christian Heimes9d50ab52018-02-27 10:17:30 +0100863 return self
Antoine Pitrou242db722013-05-01 20:52:07 +0200864
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100865 @property
Christian Heimes80ed3532019-05-17 13:08:14 +0200866 @_sslcopydoc
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100867 def context(self):
868 return self._context
869
870 @context.setter
871 def context(self, ctx):
872 self._context = ctx
873 self._sslobj.context = ctx
Bill Janssen6e027db2007-11-15 22:23:56 +0000874
Christian Heimes99a65702016-09-10 23:44:53 +0200875 @property
Christian Heimes80ed3532019-05-17 13:08:14 +0200876 @_sslcopydoc
Christian Heimes99a65702016-09-10 23:44:53 +0200877 def session(self):
Christian Heimes99a65702016-09-10 23:44:53 +0200878 if self._sslobj is not None:
879 return self._sslobj.session
880
881 @session.setter
882 def session(self, session):
883 self._session = session
884 if self._sslobj is not None:
885 self._sslobj.session = session
886
887 @property
Christian Heimes80ed3532019-05-17 13:08:14 +0200888 @_sslcopydoc
Christian Heimes99a65702016-09-10 23:44:53 +0200889 def session_reused(self):
Christian Heimes99a65702016-09-10 23:44:53 +0200890 if self._sslobj is not None:
891 return self._sslobj.session_reused
892
Guido van Rossumb7b030e2007-11-16 01:28:45 +0000893 def dup(self):
Serhiy Storchaka42b1d612018-12-06 22:36:55 +0200894 raise NotImplementedError("Can't dup() %s instances" %
895 self.__class__.__name__)
Guido van Rossumb7b030e2007-11-16 01:28:45 +0000896
Bill Janssen6e027db2007-11-15 22:23:56 +0000897 def _checkClosed(self, msg=None):
898 # raise an exception here if you wish to check for spurious closes
899 pass
900
Antoine Pitrou242db722013-05-01 20:52:07 +0200901 def _check_connected(self):
902 if not self._connected:
903 # getpeername() will raise ENOTCONN if the socket is really
904 # not connected; note that we can be connected even without
905 # _connected being set, e.g. if connect() first returned
906 # EAGAIN.
907 self.getpeername()
908
Martin Panterf6b1d662016-03-28 00:22:09 +0000909 def read(self, len=1024, buffer=None):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000910 """Read up to LEN bytes and return them.
911 Return zero-length string on EOF."""
912
Bill Janssen6e027db2007-11-15 22:23:56 +0000913 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +0100914 if self._sslobj is None:
Antoine Pitrou60a26e02013-07-20 19:35:16 +0200915 raise ValueError("Read on closed or unwrapped SSL socket.")
Bill Janssen6e027db2007-11-15 22:23:56 +0000916 try:
Christian Heimes141c5e82018-02-24 21:10:57 +0100917 if buffer is not None:
918 return self._sslobj.read(len, buffer)
919 else:
920 return self._sslobj.read(len)
Bill Janssen6e027db2007-11-15 22:23:56 +0000921 except SSLError as x:
922 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
Antoine Pitrou24e561a2010-09-03 18:38:17 +0000923 if buffer is not None:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000924 return 0
925 else:
926 return b''
Bill Janssen6e027db2007-11-15 22:23:56 +0000927 else:
928 raise
Thomas Woutersed03b412007-08-28 21:37:11 +0000929
930 def write(self, data):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000931 """Write DATA to the underlying SSL channel. Returns
932 number of bytes of DATA actually transmitted."""
933
Bill Janssen6e027db2007-11-15 22:23:56 +0000934 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +0100935 if self._sslobj is None:
Antoine Pitrou60a26e02013-07-20 19:35:16 +0200936 raise ValueError("Write on closed or unwrapped SSL socket.")
Thomas Woutersed03b412007-08-28 21:37:11 +0000937 return self._sslobj.write(data)
938
Christian Heimes80ed3532019-05-17 13:08:14 +0200939 @_sslcopydoc
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000940 def getpeercert(self, binary_form=False):
Bill Janssen6e027db2007-11-15 22:23:56 +0000941 self._checkClosed()
Antoine Pitrou242db722013-05-01 20:52:07 +0200942 self._check_connected()
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200943 return self._sslobj.getpeercert(binary_form)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000944
Christian Heimes80ed3532019-05-17 13:08:14 +0200945 @_sslcopydoc
Antoine Pitroud5d17eb2012-03-22 00:23:03 +0100946 def selected_npn_protocol(self):
947 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +0100948 if self._sslobj is None or not _ssl.HAS_NPN:
Antoine Pitroud5d17eb2012-03-22 00:23:03 +0100949 return None
950 else:
951 return self._sslobj.selected_npn_protocol()
952
Christian Heimes80ed3532019-05-17 13:08:14 +0200953 @_sslcopydoc
Benjamin Petersoncca27322015-01-23 16:35:37 -0500954 def selected_alpn_protocol(self):
955 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +0100956 if self._sslobj is None or not _ssl.HAS_ALPN:
Benjamin Petersoncca27322015-01-23 16:35:37 -0500957 return None
958 else:
959 return self._sslobj.selected_alpn_protocol()
960
Christian Heimes80ed3532019-05-17 13:08:14 +0200961 @_sslcopydoc
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000962 def cipher(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000963 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +0100964 if self._sslobj is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000965 return None
966 else:
967 return self._sslobj.cipher()
Thomas Woutersed03b412007-08-28 21:37:11 +0000968
Christian Heimes80ed3532019-05-17 13:08:14 +0200969 @_sslcopydoc
Benjamin Peterson4cb17812015-01-07 11:14:26 -0600970 def shared_ciphers(self):
971 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +0100972 if self._sslobj is None:
Benjamin Peterson4cb17812015-01-07 11:14:26 -0600973 return None
Christian Heimes141c5e82018-02-24 21:10:57 +0100974 else:
975 return self._sslobj.shared_ciphers()
Benjamin Peterson4cb17812015-01-07 11:14:26 -0600976
Christian Heimes80ed3532019-05-17 13:08:14 +0200977 @_sslcopydoc
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +0100978 def compression(self):
979 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +0100980 if self._sslobj is None:
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +0100981 return None
982 else:
983 return self._sslobj.compression()
984
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000985 def send(self, data, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +0000986 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +0100987 if self._sslobj is not None:
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000988 if flags != 0:
989 raise ValueError(
990 "non-zero flags not allowed in calls to send() on %s" %
991 self.__class__)
Antoine Pitroub4bebda2014-04-29 10:03:28 +0200992 return self._sslobj.write(data)
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000993 else:
Mads Jensen746cc752018-01-27 13:34:28 +0100994 return super().send(data, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +0000995
Antoine Pitroua468adc2010-09-14 14:43:44 +0000996 def sendto(self, data, flags_or_addr, addr=None):
Bill Janssen6e027db2007-11-15 22:23:56 +0000997 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +0100998 if self._sslobj is not None:
Bill Janssen980f3142008-06-29 00:05:51 +0000999 raise ValueError("sendto not allowed on instances of %s" %
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001000 self.__class__)
Antoine Pitroua468adc2010-09-14 14:43:44 +00001001 elif addr is None:
Mads Jensen746cc752018-01-27 13:34:28 +01001002 return super().sendto(data, flags_or_addr)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001003 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001004 return super().sendto(data, flags_or_addr, addr)
Thomas Woutersed03b412007-08-28 21:37:11 +00001005
Nick Coghlan513886a2011-08-28 00:00:27 +10001006 def sendmsg(self, *args, **kwargs):
1007 # Ensure programs don't send data unencrypted if they try to
1008 # use this method.
1009 raise NotImplementedError("sendmsg not allowed on instances of %s" %
1010 self.__class__)
1011
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001012 def sendall(self, data, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001013 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001014 if self._sslobj is not None:
Giampaolo Rodolà374f8352010-08-29 12:08:09 +00001015 if flags != 0:
1016 raise ValueError(
1017 "non-zero flags not allowed in calls to sendall() on %s" %
1018 self.__class__)
Bill Janssen6e027db2007-11-15 22:23:56 +00001019 count = 0
Christian Heimes888bbdc2017-09-07 14:18:21 -07001020 with memoryview(data) as view, view.cast("B") as byte_view:
1021 amount = len(byte_view)
1022 while count < amount:
1023 v = self.send(byte_view[count:])
1024 count += v
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001025 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001026 return super().sendall(data, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001027
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02001028 def sendfile(self, file, offset=0, count=None):
1029 """Send a file, possibly by using os.sendfile() if this is a
1030 clear-text socket. Return the total number of bytes sent.
1031 """
Christian Heimes141c5e82018-02-24 21:10:57 +01001032 if self._sslobj is not None:
1033 return self._sendfile_use_send(file, offset, count)
1034 else:
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02001035 # os.sendfile() works with plain sockets only
1036 return super().sendfile(file, offset, count)
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02001037
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001038 def recv(self, buflen=1024, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001039 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001040 if self._sslobj is not None:
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001041 if flags != 0:
1042 raise ValueError(
Antoine Pitrou5733c082010-03-22 14:49:10 +00001043 "non-zero flags not allowed in calls to recv() on %s" %
1044 self.__class__)
1045 return self.read(buflen)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001046 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001047 return super().recv(buflen, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001048
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001049 def recv_into(self, buffer, nbytes=None, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001050 self._checkClosed()
1051 if buffer and (nbytes is None):
1052 nbytes = len(buffer)
1053 elif nbytes is None:
1054 nbytes = 1024
Christian Heimes141c5e82018-02-24 21:10:57 +01001055 if self._sslobj is not None:
Bill Janssen6e027db2007-11-15 22:23:56 +00001056 if flags != 0:
1057 raise ValueError(
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001058 "non-zero flags not allowed in calls to recv_into() on %s" %
1059 self.__class__)
Antoine Pitrou5733c082010-03-22 14:49:10 +00001060 return self.read(nbytes, buffer)
Bill Janssen6e027db2007-11-15 22:23:56 +00001061 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001062 return super().recv_into(buffer, nbytes, flags)
Bill Janssen6e027db2007-11-15 22:23:56 +00001063
Antoine Pitroua468adc2010-09-14 14:43:44 +00001064 def recvfrom(self, buflen=1024, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001065 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001066 if self._sslobj is not None:
Bill Janssen980f3142008-06-29 00:05:51 +00001067 raise ValueError("recvfrom not allowed on instances of %s" %
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001068 self.__class__)
1069 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001070 return super().recvfrom(buflen, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001071
Bill Janssen58afe4c2008-09-08 16:45:19 +00001072 def recvfrom_into(self, buffer, nbytes=None, flags=0):
1073 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001074 if self._sslobj is not None:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001075 raise ValueError("recvfrom_into not allowed on instances of %s" %
1076 self.__class__)
1077 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001078 return super().recvfrom_into(buffer, nbytes, flags)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001079
Nick Coghlan513886a2011-08-28 00:00:27 +10001080 def recvmsg(self, *args, **kwargs):
1081 raise NotImplementedError("recvmsg not allowed on instances of %s" %
1082 self.__class__)
1083
1084 def recvmsg_into(self, *args, **kwargs):
1085 raise NotImplementedError("recvmsg_into not allowed on instances of "
1086 "%s" % self.__class__)
1087
Christian Heimes80ed3532019-05-17 13:08:14 +02001088 @_sslcopydoc
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001089 def pending(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001090 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001091 if self._sslobj is not None:
Bill Janssen6e027db2007-11-15 22:23:56 +00001092 return self._sslobj.pending()
1093 else:
1094 return 0
1095
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001096 def shutdown(self, how):
Bill Janssen6e027db2007-11-15 22:23:56 +00001097 self._checkClosed()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001098 self._sslobj = None
Mads Jensen746cc752018-01-27 13:34:28 +01001099 super().shutdown(how)
Thomas Woutersed03b412007-08-28 21:37:11 +00001100
Christian Heimes80ed3532019-05-17 13:08:14 +02001101 @_sslcopydoc
Ezio Melottidc55e672010-01-18 09:15:14 +00001102 def unwrap(self):
Bill Janssen40a0f662008-08-12 16:56:25 +00001103 if self._sslobj:
Christian Heimes141c5e82018-02-24 21:10:57 +01001104 s = self._sslobj.shutdown()
Bill Janssen40a0f662008-08-12 16:56:25 +00001105 self._sslobj = None
1106 return s
1107 else:
1108 raise ValueError("No SSL wrapper around " + str(self))
1109
Christian Heimes80ed3532019-05-17 13:08:14 +02001110 @_sslcopydoc
Christian Heimes9fb051f2018-09-23 08:32:31 +02001111 def verify_client_post_handshake(self):
1112 if self._sslobj:
1113 return self._sslobj.verify_client_post_handshake()
1114 else:
1115 raise ValueError("No SSL wrapper around " + str(self))
1116
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001117 def _real_close(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001118 self._sslobj = None
Mads Jensen746cc752018-01-27 13:34:28 +01001119 super()._real_close()
Bill Janssen6e027db2007-11-15 22:23:56 +00001120
Christian Heimes80ed3532019-05-17 13:08:14 +02001121 @_sslcopydoc
Bill Janssen48dc27c2007-12-05 03:38:10 +00001122 def do_handshake(self, block=False):
Antoine Pitrou242db722013-05-01 20:52:07 +02001123 self._check_connected()
Bill Janssen48dc27c2007-12-05 03:38:10 +00001124 timeout = self.gettimeout()
Bill Janssen6e027db2007-11-15 22:23:56 +00001125 try:
Bill Janssen48dc27c2007-12-05 03:38:10 +00001126 if timeout == 0.0 and block:
1127 self.settimeout(None)
Bill Janssen6e027db2007-11-15 22:23:56 +00001128 self._sslobj.do_handshake()
Bill Janssen48dc27c2007-12-05 03:38:10 +00001129 finally:
1130 self.settimeout(timeout)
Thomas Woutersed03b412007-08-28 21:37:11 +00001131
Antoine Pitroub4410db2011-05-18 18:51:06 +02001132 def _real_connect(self, addr, connect_ex):
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001133 if self.server_side:
1134 raise ValueError("can't connect in server-side mode")
Thomas Woutersed03b412007-08-28 21:37:11 +00001135 # Here we assume that the socket is client-side, and not
1136 # connected at the time of the call. We connect it, then wrap it.
Christian Heimes141c5e82018-02-24 21:10:57 +01001137 if self._connected or self._sslobj is not None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001138 raise ValueError("attempt to connect already-connected SSLSocket!")
Christian Heimes141c5e82018-02-24 21:10:57 +01001139 self._sslobj = self.context._wrap_socket(
1140 self, False, self.server_hostname,
1141 owner=self, session=self._session
1142 )
Bill Janssen54cc54c2007-12-14 22:08:56 +00001143 try:
Antoine Pitroub4410db2011-05-18 18:51:06 +02001144 if connect_ex:
Mads Jensen746cc752018-01-27 13:34:28 +01001145 rc = super().connect_ex(addr)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001146 else:
Antoine Pitroub4410db2011-05-18 18:51:06 +02001147 rc = None
Mads Jensen746cc752018-01-27 13:34:28 +01001148 super().connect(addr)
Antoine Pitroub4410db2011-05-18 18:51:06 +02001149 if not rc:
Antoine Pitrou242db722013-05-01 20:52:07 +02001150 self._connected = True
Antoine Pitroub4410db2011-05-18 18:51:06 +02001151 if self.do_handshake_on_connect:
1152 self.do_handshake()
Antoine Pitroub4410db2011-05-18 18:51:06 +02001153 return rc
Christian Heimes1aa9a752013-12-02 02:41:19 +01001154 except (OSError, ValueError):
Antoine Pitroub4410db2011-05-18 18:51:06 +02001155 self._sslobj = None
1156 raise
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001157
1158 def connect(self, addr):
1159 """Connects to remote ADDR, and then wraps the connection in
1160 an SSL channel."""
1161 self._real_connect(addr, False)
1162
1163 def connect_ex(self, addr):
1164 """Connects to remote ADDR, and then wraps the connection in
1165 an SSL channel."""
1166 return self._real_connect(addr, True)
Thomas Woutersed03b412007-08-28 21:37:11 +00001167
1168 def accept(self):
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001169 """Accepts a new connection from a remote client, and returns
1170 a tuple containing that new connection wrapped with a server-side
1171 SSL channel, and the address of the remote client."""
1172
Mads Jensen746cc752018-01-27 13:34:28 +01001173 newsock, addr = super().accept()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01001174 newsock = self.context.wrap_socket(newsock,
1175 do_handshake_on_connect=self.do_handshake_on_connect,
1176 suppress_ragged_eofs=self.suppress_ragged_eofs,
1177 server_side=True)
1178 return newsock, addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001179
Christian Heimes80ed3532019-05-17 13:08:14 +02001180 @_sslcopydoc
Antoine Pitroud6494802011-07-21 01:11:30 +02001181 def get_channel_binding(self, cb_type="tls-unique"):
Christian Heimes141c5e82018-02-24 21:10:57 +01001182 if self._sslobj is not None:
1183 return self._sslobj.get_channel_binding(cb_type)
1184 else:
1185 if cb_type not in CHANNEL_BINDING_TYPES:
1186 raise ValueError(
1187 "{0} channel binding type not implemented".format(cb_type)
1188 )
Antoine Pitroud6494802011-07-21 01:11:30 +02001189 return None
Antoine Pitroud6494802011-07-21 01:11:30 +02001190
Christian Heimes80ed3532019-05-17 13:08:14 +02001191 @_sslcopydoc
Antoine Pitrou47e40422014-09-04 21:00:10 +02001192 def version(self):
Christian Heimes141c5e82018-02-24 21:10:57 +01001193 if self._sslobj is not None:
1194 return self._sslobj.version()
1195 else:
Antoine Pitrou47e40422014-09-04 21:00:10 +02001196 return None
Antoine Pitrou47e40422014-09-04 21:00:10 +02001197
Bill Janssen54cc54c2007-12-14 22:08:56 +00001198
Christian Heimes4df60f12017-09-15 20:26:05 +02001199# Python does not support forward declaration of types.
1200SSLContext.sslsocket_class = SSLSocket
1201SSLContext.sslobject_class = SSLObject
1202
1203
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001204def wrap_socket(sock, keyfile=None, certfile=None,
1205 server_side=False, cert_reqs=CERT_NONE,
Christian Heimes598894f2016-09-05 23:19:05 +02001206 ssl_version=PROTOCOL_TLS, ca_certs=None,
Bill Janssen48dc27c2007-12-05 03:38:10 +00001207 do_handshake_on_connect=True,
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001208 suppress_ragged_eofs=True,
1209 ciphers=None):
Christian Heimes9d50ab52018-02-27 10:17:30 +01001210
1211 if server_side and not certfile:
1212 raise ValueError("certfile must be specified for server-side "
1213 "operations")
1214 if keyfile and not certfile:
1215 raise ValueError("certfile must be specified")
1216 context = SSLContext(ssl_version)
1217 context.verify_mode = cert_reqs
1218 if ca_certs:
1219 context.load_verify_locations(ca_certs)
1220 if certfile:
1221 context.load_cert_chain(certfile, keyfile)
1222 if ciphers:
1223 context.set_ciphers(ciphers)
1224 return context.wrap_socket(
1225 sock=sock, server_side=server_side,
1226 do_handshake_on_connect=do_handshake_on_connect,
1227 suppress_ragged_eofs=suppress_ragged_eofs
1228 )
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001229
Thomas Woutersed03b412007-08-28 21:37:11 +00001230# some utility functions
1231
1232def cert_time_to_seconds(cert_time):
Antoine Pitrouc695c952014-04-28 20:57:36 +02001233 """Return the time in seconds since the Epoch, given the timestring
1234 representing the "notBefore" or "notAfter" date from a certificate
1235 in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale).
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001236
Antoine Pitrouc695c952014-04-28 20:57:36 +02001237 "notBefore" or "notAfter" dates must use UTC (RFC 5280).
1238
1239 Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1240 UTC should be specified as GMT (see ASN1_TIME_print())
1241 """
1242 from time import strptime
1243 from calendar import timegm
1244
1245 months = (
1246 "Jan","Feb","Mar","Apr","May","Jun",
1247 "Jul","Aug","Sep","Oct","Nov","Dec"
1248 )
1249 time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT
1250 try:
1251 month_number = months.index(cert_time[:3].title()) + 1
1252 except ValueError:
1253 raise ValueError('time data %r does not match '
1254 'format "%%b%s"' % (cert_time, time_format))
1255 else:
1256 # found valid month
1257 tt = strptime(cert_time[3:], time_format)
1258 # return an integer, the previous mktime()-based implementation
1259 # returned a float (fractional seconds are always zero here).
1260 return timegm((tt[0], month_number) + tt[2:6])
Thomas Woutersed03b412007-08-28 21:37:11 +00001261
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001262PEM_HEADER = "-----BEGIN CERTIFICATE-----"
1263PEM_FOOTER = "-----END CERTIFICATE-----"
1264
1265def DER_cert_to_PEM_cert(der_cert_bytes):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001266 """Takes a certificate in binary DER format and returns the
1267 PEM version of it as a string."""
1268
Bill Janssen6e027db2007-11-15 22:23:56 +00001269 f = str(base64.standard_b64encode(der_cert_bytes), 'ASCII', 'strict')
INADA Naokib75a2282017-10-02 16:33:42 +09001270 ss = [PEM_HEADER]
1271 ss += [f[i:i+64] for i in range(0, len(f), 64)]
1272 ss.append(PEM_FOOTER + '\n')
1273 return '\n'.join(ss)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001274
1275def PEM_cert_to_DER_cert(pem_cert_string):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001276 """Takes a certificate in ASCII PEM format and returns the
1277 DER-encoded version of it as a byte sequence"""
1278
1279 if not pem_cert_string.startswith(PEM_HEADER):
1280 raise ValueError("Invalid PEM encoding; must start with %s"
1281 % PEM_HEADER)
1282 if not pem_cert_string.strip().endswith(PEM_FOOTER):
1283 raise ValueError("Invalid PEM encoding; must end with %s"
1284 % PEM_FOOTER)
1285 d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
Georg Brandl706824f2009-06-04 09:42:55 +00001286 return base64.decodebytes(d.encode('ASCII', 'strict'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001287
Christian Heimes598894f2016-09-05 23:19:05 +02001288def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001289 """Retrieve the certificate from the server at the specified address,
1290 and return it as a PEM-encoded string.
1291 If 'ca_certs' is specified, validate the server cert against it.
1292 If 'ssl_version' is specified, use it in the connection attempt."""
1293
1294 host, port = addr
Christian Heimes67986f92013-11-23 22:43:47 +01001295 if ca_certs is not None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001296 cert_reqs = CERT_REQUIRED
1297 else:
1298 cert_reqs = CERT_NONE
Christian Heimes67986f92013-11-23 22:43:47 +01001299 context = _create_stdlib_context(ssl_version,
1300 cert_reqs=cert_reqs,
1301 cafile=ca_certs)
1302 with create_connection(addr) as sock:
1303 with context.wrap_socket(sock) as sslsock:
1304 dercert = sslsock.getpeercert(True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001305 return DER_cert_to_PEM_cert(dercert)
1306
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001307def get_protocol_name(protocol_code):
Victor Stinner3de49192011-05-09 00:42:58 +02001308 return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')