blob: 620ddaa93f962c730d565a66193bcf4a2fce9759 [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
Ethan Furmana02cb472021-04-21 10:20:44 -070097from enum import _simple_enum, _test_simple_enum
Thomas Woutersed03b412007-08-28 21:37:11 +000098
99import _ssl # if we can't import it, let the error propagate
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000100
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000101from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
Christian Heimes99a65702016-09-10 23:44:53 +0200102from _ssl import _SSLContext, MemoryBIO, SSLSession
Antoine Pitrou41032a62011-10-27 23:56:55 +0200103from _ssl import (
104 SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
Christian Heimesb3ad0e52017-09-08 12:00:19 -0700105 SSLSyscallError, SSLEOFError, SSLCertVerificationError
Antoine Pitrou41032a62011-10-27 23:56:55 +0200106 )
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100107from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
Victor Stinnerbeeb5122014-11-28 13:28:25 +0100108from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes
109try:
110 from _ssl import RAND_egd
111except ImportError:
112 # LibreSSL does not provide RAND_egd
113 pass
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100114
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100115
Christian Heimes698dde12018-02-27 11:54:43 +0100116from _ssl import (
117 HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_SSLv2, HAS_SSLv3, HAS_TLSv1,
118 HAS_TLSv1_1, HAS_TLSv1_2, HAS_TLSv1_3
119)
120from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION
Antoine Pitroub9ac25d2011-07-08 18:47:06 +0200121
Christian Heimes3aeacad2016-09-10 00:19:35 +0200122
orlnub1230fb9fad2018-09-12 20:28:53 +0300123_IntEnum._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200124 '_SSLMethod', __name__,
125 lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23',
126 source=_ssl)
127
orlnub1230fb9fad2018-09-12 20:28:53 +0300128_IntFlag._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200129 'Options', __name__,
130 lambda name: name.startswith('OP_'),
131 source=_ssl)
132
orlnub1230fb9fad2018-09-12 20:28:53 +0300133_IntEnum._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200134 'AlertDescription', __name__,
135 lambda name: name.startswith('ALERT_DESCRIPTION_'),
136 source=_ssl)
137
orlnub1230fb9fad2018-09-12 20:28:53 +0300138_IntEnum._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200139 'SSLErrorNumber', __name__,
140 lambda name: name.startswith('SSL_ERROR_'),
141 source=_ssl)
142
orlnub1230fb9fad2018-09-12 20:28:53 +0300143_IntFlag._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200144 'VerifyFlags', __name__,
145 lambda name: name.startswith('VERIFY_'),
146 source=_ssl)
147
orlnub1230fb9fad2018-09-12 20:28:53 +0300148_IntEnum._convert_(
Christian Heimes3aeacad2016-09-10 00:19:35 +0200149 'VerifyMode', __name__,
150 lambda name: name.startswith('CERT_'),
151 source=_ssl)
152
Christian Heimes598894f2016-09-05 23:19:05 +0200153PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_SSLv23 = _SSLMethod.PROTOCOL_TLS
Antoine Pitrou172f0252014-04-18 20:33:08 +0200154_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()}
155
Christian Heimes3aeacad2016-09-10 00:19:35 +0200156_SSLv2_IF_EXISTS = getattr(_SSLMethod, 'PROTOCOL_SSLv2', None)
157
Antoine Pitrou2463e5f2013-03-28 22:24:43 +0100158
Ethan Furmana02cb472021-04-21 10:20:44 -0700159@_simple_enum(_IntEnum)
160class TLSVersion:
Christian Heimes698dde12018-02-27 11:54:43 +0100161 MINIMUM_SUPPORTED = _ssl.PROTO_MINIMUM_SUPPORTED
162 SSLv3 = _ssl.PROTO_SSLv3
163 TLSv1 = _ssl.PROTO_TLSv1
164 TLSv1_1 = _ssl.PROTO_TLSv1_1
165 TLSv1_2 = _ssl.PROTO_TLSv1_2
166 TLSv1_3 = _ssl.PROTO_TLSv1_3
167 MAXIMUM_SUPPORTED = _ssl.PROTO_MAXIMUM_SUPPORTED
168
169
Ethan Furmana02cb472021-04-21 10:20:44 -0700170@_simple_enum(_IntEnum)
171class _TLSContentType:
Christian Heimesc7f70692019-05-31 11:44:05 +0200172 """Content types (record layer)
173
174 See RFC 8446, section B.1
175 """
176 CHANGE_CIPHER_SPEC = 20
177 ALERT = 21
178 HANDSHAKE = 22
179 APPLICATION_DATA = 23
180 # pseudo content types
181 HEADER = 0x100
182 INNER_CONTENT_TYPE = 0x101
183
184
Ethan Furmana02cb472021-04-21 10:20:44 -0700185@_simple_enum(_IntEnum)
186class _TLSAlertType:
Christian Heimesc7f70692019-05-31 11:44:05 +0200187 """Alert types for TLSContentType.ALERT messages
188
189 See RFC 8466, section B.2
190 """
191 CLOSE_NOTIFY = 0
192 UNEXPECTED_MESSAGE = 10
193 BAD_RECORD_MAC = 20
194 DECRYPTION_FAILED = 21
195 RECORD_OVERFLOW = 22
196 DECOMPRESSION_FAILURE = 30
197 HANDSHAKE_FAILURE = 40
198 NO_CERTIFICATE = 41
199 BAD_CERTIFICATE = 42
200 UNSUPPORTED_CERTIFICATE = 43
201 CERTIFICATE_REVOKED = 44
202 CERTIFICATE_EXPIRED = 45
203 CERTIFICATE_UNKNOWN = 46
204 ILLEGAL_PARAMETER = 47
205 UNKNOWN_CA = 48
206 ACCESS_DENIED = 49
207 DECODE_ERROR = 50
208 DECRYPT_ERROR = 51
209 EXPORT_RESTRICTION = 60
210 PROTOCOL_VERSION = 70
211 INSUFFICIENT_SECURITY = 71
212 INTERNAL_ERROR = 80
213 INAPPROPRIATE_FALLBACK = 86
214 USER_CANCELED = 90
215 NO_RENEGOTIATION = 100
216 MISSING_EXTENSION = 109
217 UNSUPPORTED_EXTENSION = 110
218 CERTIFICATE_UNOBTAINABLE = 111
219 UNRECOGNIZED_NAME = 112
220 BAD_CERTIFICATE_STATUS_RESPONSE = 113
221 BAD_CERTIFICATE_HASH_VALUE = 114
222 UNKNOWN_PSK_IDENTITY = 115
223 CERTIFICATE_REQUIRED = 116
224 NO_APPLICATION_PROTOCOL = 120
225
226
Ethan Furmana02cb472021-04-21 10:20:44 -0700227@_simple_enum(_IntEnum)
228class _TLSMessageType:
Christian Heimesc7f70692019-05-31 11:44:05 +0200229 """Message types (handshake protocol)
230
231 See RFC 8446, section B.3
232 """
233 HELLO_REQUEST = 0
234 CLIENT_HELLO = 1
235 SERVER_HELLO = 2
236 HELLO_VERIFY_REQUEST = 3
237 NEWSESSION_TICKET = 4
238 END_OF_EARLY_DATA = 5
239 HELLO_RETRY_REQUEST = 6
240 ENCRYPTED_EXTENSIONS = 8
241 CERTIFICATE = 11
242 SERVER_KEY_EXCHANGE = 12
243 CERTIFICATE_REQUEST = 13
244 SERVER_DONE = 14
245 CERTIFICATE_VERIFY = 15
246 CLIENT_KEY_EXCHANGE = 16
247 FINISHED = 20
248 CERTIFICATE_URL = 21
249 CERTIFICATE_STATUS = 22
250 SUPPLEMENTAL_DATA = 23
251 KEY_UPDATE = 24
252 NEXT_PROTO = 67
253 MESSAGE_HASH = 254
254 CHANGE_CIPHER_SPEC = 0x0101
255
256
Christian Heimes46bebee2013-06-09 19:03:31 +0200257if sys.platform == "win32":
Christian Heimes44109d72013-11-22 01:51:30 +0100258 from _ssl import enum_certificates, enum_crls
Christian Heimes46bebee2013-06-09 19:03:31 +0200259
Victor Stinnereb0d3592020-05-01 02:38:00 +0200260from socket import socket, SOCK_STREAM, create_connection
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100261from socket import SOL_SOCKET, SO_TYPE
Christian Heimesaef12832018-02-24 14:35:56 +0100262import socket as _socket
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000263import base64 # for DER-to-PEM translation
Antoine Pitroude8cf322010-04-26 17:29:05 +0000264import errno
Steve Dower33bc4a22016-05-26 12:18:12 -0700265import warnings
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000266
Andrew Svetlov0832af62012-12-18 23:10:48 +0200267
268socket_error = OSError # keep that public name in module namespace
269
Christian Heimes141c5e82018-02-24 21:10:57 +0100270CHANNEL_BINDING_TYPES = ['tls-unique']
Thomas Woutersed03b412007-08-28 21:37:11 +0000271
Christian Heimes61d478c2018-01-27 15:51:38 +0100272HAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT')
273
Christian Heimes03d13c02016-09-06 20:06:47 +0200274
Christian Heimes892d66e2018-01-29 14:10:18 +0100275_RESTRICTED_SERVER_CIPHERS = _DEFAULT_CIPHERS
Christian Heimes4c05b472013-11-23 15:58:30 +0100276
Christian Heimes61d478c2018-01-27 15:51:38 +0100277CertificateError = SSLCertVerificationError
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000278
279
Mandeep Singhede2ac92017-11-27 04:01:27 +0530280def _dnsname_match(dn, hostname):
Georg Brandl72c98d32013-10-27 07:16:53 +0100281 """Matching according to RFC 6125, section 6.4.3
282
Christian Heimesaef12832018-02-24 14:35:56 +0100283 - Hostnames are compared lower case.
284 - For IDNA, both dn and hostname must be encoded as IDN A-label (ACE).
285 - Partial wildcards like 'www*.example.org', multiple wildcards, sole
286 wildcard or wildcards in labels other then the left-most label are not
287 supported and a CertificateError is raised.
288 - A wildcard must match at least one character.
Georg Brandl72c98d32013-10-27 07:16:53 +0100289 """
Georg Brandl72c98d32013-10-27 07:16:53 +0100290 if not dn:
291 return False
292
Christian Heimesaef12832018-02-24 14:35:56 +0100293 wildcards = dn.count('*')
Georg Brandl72c98d32013-10-27 07:16:53 +0100294 # speed up common case w/o wildcards
295 if not wildcards:
296 return dn.lower() == hostname.lower()
297
Christian Heimesaef12832018-02-24 14:35:56 +0100298 if wildcards > 1:
299 raise CertificateError(
300 "too many wildcards in certificate DNS name: {!r}.".format(dn))
Georg Brandl72c98d32013-10-27 07:16:53 +0100301
Christian Heimesaef12832018-02-24 14:35:56 +0100302 dn_leftmost, sep, dn_remainder = dn.partition('.')
Georg Brandl72c98d32013-10-27 07:16:53 +0100303
Christian Heimesaef12832018-02-24 14:35:56 +0100304 if '*' in dn_remainder:
305 # Only match wildcard in leftmost segment.
306 raise CertificateError(
307 "wildcard can only be present in the leftmost label: "
308 "{!r}.".format(dn))
309
310 if not sep:
311 # no right side
312 raise CertificateError(
313 "sole wildcard without additional labels are not support: "
314 "{!r}.".format(dn))
315
316 if dn_leftmost != '*':
317 # no partial wildcard matching
318 raise CertificateError(
319 "partial wildcards in leftmost label are not supported: "
320 "{!r}.".format(dn))
321
322 hostname_leftmost, sep, hostname_remainder = hostname.partition('.')
323 if not hostname_leftmost or not sep:
324 # wildcard must match at least one char
325 return False
326 return dn_remainder.lower() == hostname_remainder.lower()
327
328
329def _inet_paton(ipname):
330 """Try to convert an IP address to packed binary form
331
332 Supports IPv4 addresses on all platforms and IPv6 on platforms with IPv6
333 support.
334 """
Christian Heimes477b1b22019-07-02 20:39:42 +0200335 # inet_aton() also accepts strings like '1', '127.1', some also trailing
336 # data like '127.0.0.1 whatever'.
337 try:
338 addr = _socket.inet_aton(ipname)
339 except OSError:
340 # not an IPv4 address
341 pass
342 else:
343 if _socket.inet_ntoa(addr) == ipname:
344 # only accept injective ipnames
345 return addr
346 else:
347 # refuse for short IPv4 notation and additional trailing data
348 raise ValueError(
349 "{!r} is not a quad-dotted IPv4 address.".format(ipname)
350 )
Christian Heimesaef12832018-02-24 14:35:56 +0100351
352 try:
353 return _socket.inet_pton(_socket.AF_INET6, ipname)
354 except OSError:
355 raise ValueError("{!r} is neither an IPv4 nor an IP6 "
356 "address.".format(ipname))
357 except AttributeError:
358 # AF_INET6 not available
359 pass
360
361 raise ValueError("{!r} is not an IPv4 address.".format(ipname))
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000362
363
Christian Heimes477b1b22019-07-02 20:39:42 +0200364def _ipaddress_match(cert_ipaddress, host_ip):
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100365 """Exact matching of IP addresses.
366
367 RFC 6125 explicitly doesn't define an algorithm for this
368 (section 1.7.2 - "Out of Scope").
369 """
Christian Heimes477b1b22019-07-02 20:39:42 +0200370 # OpenSSL may add a trailing newline to a subjectAltName's IP address,
371 # commonly woth IPv6 addresses. Strip off trailing \n.
372 ip = _inet_paton(cert_ipaddress.rstrip())
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100373 return ip == host_ip
374
375
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000376def match_hostname(cert, hostname):
377 """Verify that *cert* (in decoded format as returned by
Georg Brandl72c98d32013-10-27 07:16:53 +0100378 SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
Christian Heimesaef12832018-02-24 14:35:56 +0100379 rules are followed.
380
381 The function matches IP addresses rather than dNSNames if hostname is a
382 valid ipaddress string. IPv4 addresses are supported on all platforms.
383 IPv6 addresses are supported on platforms with IPv6 support (AF_INET6
384 and inet_pton).
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000385
386 CertificateError is raised on failure. On success, the function
387 returns nothing.
388 """
Christian Heimes2875c602021-04-19 07:27:10 +0200389 warnings.warn(
390 "ssl module: match_hostname() is deprecated",
391 category=DeprecationWarning,
392 stacklevel=2
393 )
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000394 if not cert:
Christian Heimes1aa9a752013-12-02 02:41:19 +0100395 raise ValueError("empty or no certificate, match_hostname needs a "
396 "SSL socket or SSL context with either "
397 "CERT_OPTIONAL or CERT_REQUIRED")
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100398 try:
Christian Heimesaef12832018-02-24 14:35:56 +0100399 host_ip = _inet_paton(hostname)
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100400 except ValueError:
401 # Not an IP address (common case)
402 host_ip = None
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000403 dnsnames = []
404 san = cert.get('subjectAltName', ())
405 for key, value in san:
406 if key == 'DNS':
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100407 if host_ip is None and _dnsname_match(value, hostname):
408 return
409 dnsnames.append(value)
410 elif key == 'IP Address':
411 if host_ip is not None and _ipaddress_match(value, host_ip):
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000412 return
413 dnsnames.append(value)
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200414 if not dnsnames:
415 # The subject is only checked when there is no dNSName entry
416 # in subjectAltName
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000417 for sub in cert.get('subject', ()):
418 for key, value in sub:
419 # XXX according to RFC 2818, the most specific Common Name
420 # must be used.
421 if key == 'commonName':
Georg Brandl72c98d32013-10-27 07:16:53 +0100422 if _dnsname_match(value, hostname):
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000423 return
424 dnsnames.append(value)
425 if len(dnsnames) > 1:
426 raise CertificateError("hostname %r "
427 "doesn't match either of %s"
428 % (hostname, ', '.join(map(repr, dnsnames))))
429 elif len(dnsnames) == 1:
430 raise CertificateError("hostname %r "
431 "doesn't match %r"
432 % (hostname, dnsnames[0]))
433 else:
434 raise CertificateError("no appropriate commonName or "
435 "subjectAltName fields were found")
436
437
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100438DefaultVerifyPaths = namedtuple("DefaultVerifyPaths",
Christian Heimes6d7ad132013-06-09 18:02:55 +0200439 "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env "
440 "openssl_capath")
441
442def get_default_verify_paths():
443 """Return paths to default cafile and capath.
444 """
445 parts = _ssl.get_default_verify_paths()
446
447 # environment vars shadow paths
448 cafile = os.environ.get(parts[0], parts[1])
449 capath = os.environ.get(parts[2], parts[3])
450
451 return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None,
452 capath if os.path.isdir(capath) else None,
453 *parts)
454
455
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100456class _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")):
457 """ASN.1 object identifier lookup
458 """
459 __slots__ = ()
460
461 def __new__(cls, oid):
462 return super().__new__(cls, *_txt2obj(oid, name=False))
463
464 @classmethod
465 def fromnid(cls, nid):
466 """Create _ASN1Object from OpenSSL numeric ID
467 """
468 return super().__new__(cls, *_nid2obj(nid))
469
470 @classmethod
471 def fromname(cls, name):
472 """Create _ASN1Object from short name, long name or OID
473 """
474 return super().__new__(cls, *_txt2obj(name, name=True))
475
476
Christian Heimes72d28502013-11-23 13:56:58 +0100477class Purpose(_ASN1Object, _Enum):
478 """SSLContext purpose flags with X509v3 Extended Key Usage objects
479 """
480 SERVER_AUTH = '1.3.6.1.5.5.7.3.1'
481 CLIENT_AUTH = '1.3.6.1.5.5.7.3.2'
482
483
Antoine Pitrou152efa22010-05-16 18:19:27 +0000484class SSLContext(_SSLContext):
485 """An SSLContext holds various SSL-related configuration options and
486 data, such as certificates and possibly a private key."""
Christian Heimes72d28502013-11-23 13:56:58 +0100487 _windows_cert_stores = ("CA", "ROOT")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000488
Christian Heimes4df60f12017-09-15 20:26:05 +0200489 sslsocket_class = None # SSLSocket is assigned later.
490 sslobject_class = None # SSLObject is assigned later.
491
Christian Heimes2875c602021-04-19 07:27:10 +0200492 def __new__(cls, protocol=None, *args, **kwargs):
493 if protocol is None:
494 warnings.warn(
495 "ssl module: "
496 "SSLContext() without protocol argument is deprecated.",
497 category=DeprecationWarning,
498 stacklevel=2
499 )
500 protocol = PROTOCOL_TLS
Antoine Pitrou8f85f902012-01-03 22:46:48 +0100501 self = _SSLContext.__new__(cls, protocol)
Antoine Pitrou8f85f902012-01-03 22:46:48 +0100502 return self
Antoine Pitrou152efa22010-05-16 18:19:27 +0000503
Christian Heimes11a14932018-02-24 02:35:08 +0100504 def _encode_hostname(self, hostname):
505 if hostname is None:
506 return None
507 elif isinstance(hostname, str):
508 return hostname.encode('idna').decode('ascii')
509 else:
510 return hostname.decode('ascii')
Antoine Pitrou152efa22010-05-16 18:19:27 +0000511
512 def wrap_socket(self, sock, server_side=False,
513 do_handshake_on_connect=True,
Antoine Pitroud5323212010-10-22 18:19:07 +0000514 suppress_ragged_eofs=True,
Christian Heimes99a65702016-09-10 23:44:53 +0200515 server_hostname=None, session=None):
Christian Heimes11a14932018-02-24 02:35:08 +0100516 # SSLSocket class handles server_hostname encoding before it calls
517 # ctx._wrap_socket()
Christian Heimes9d50ab52018-02-27 10:17:30 +0100518 return self.sslsocket_class._create(
Christian Heimes4df60f12017-09-15 20:26:05 +0200519 sock=sock,
520 server_side=server_side,
521 do_handshake_on_connect=do_handshake_on_connect,
522 suppress_ragged_eofs=suppress_ragged_eofs,
523 server_hostname=server_hostname,
Christian Heimes9d50ab52018-02-27 10:17:30 +0100524 context=self,
525 session=session
Christian Heimes4df60f12017-09-15 20:26:05 +0200526 )
Antoine Pitrou152efa22010-05-16 18:19:27 +0000527
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200528 def wrap_bio(self, incoming, outgoing, server_side=False,
Christian Heimes99a65702016-09-10 23:44:53 +0200529 server_hostname=None, session=None):
Christian Heimes11a14932018-02-24 02:35:08 +0100530 # Need to encode server_hostname here because _wrap_bio() can only
531 # handle ASCII str.
Christian Heimes9d50ab52018-02-27 10:17:30 +0100532 return self.sslobject_class._create(
Christian Heimes11a14932018-02-24 02:35:08 +0100533 incoming, outgoing, server_side=server_side,
Christian Heimes141c5e82018-02-24 21:10:57 +0100534 server_hostname=self._encode_hostname(server_hostname),
Christian Heimes9d50ab52018-02-27 10:17:30 +0100535 session=session, context=self,
Christian Heimes11a14932018-02-24 02:35:08 +0100536 )
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200537
Antoine Pitroud5d17eb2012-03-22 00:23:03 +0100538 def set_npn_protocols(self, npn_protocols):
Christian Heimes2875c602021-04-19 07:27:10 +0200539 warnings.warn("NPN is deprecated, use ALPN instead", stacklevel=2)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +0100540 protos = bytearray()
541 for protocol in npn_protocols:
542 b = bytes(protocol, 'ascii')
543 if len(b) == 0 or len(b) > 255:
544 raise SSLError('NPN protocols must be 1 to 255 in length')
545 protos.append(len(b))
546 protos.extend(b)
547
548 self._set_npn_protocols(protos)
549
Christian Heimes11a14932018-02-24 02:35:08 +0100550 def set_servername_callback(self, server_name_callback):
551 if server_name_callback is None:
552 self.sni_callback = None
553 else:
554 if not callable(server_name_callback):
555 raise TypeError("not a callable object")
556
557 def shim_cb(sslobj, servername, sslctx):
558 servername = self._encode_hostname(servername)
559 return server_name_callback(sslobj, servername, sslctx)
560
561 self.sni_callback = shim_cb
562
Benjamin Petersoncca27322015-01-23 16:35:37 -0500563 def set_alpn_protocols(self, alpn_protocols):
564 protos = bytearray()
565 for protocol in alpn_protocols:
566 b = bytes(protocol, 'ascii')
567 if len(b) == 0 or len(b) > 255:
568 raise SSLError('ALPN protocols must be 1 to 255 in length')
569 protos.append(len(b))
570 protos.extend(b)
571
572 self._set_alpn_protocols(protos)
573
Christian Heimes72d28502013-11-23 13:56:58 +0100574 def _load_windows_store_certs(self, storename, purpose):
575 certs = bytearray()
Steve Dower33bc4a22016-05-26 12:18:12 -0700576 try:
577 for cert, encoding, trust in enum_certificates(storename):
578 # CA certs are never PKCS#7 encoded
579 if encoding == "x509_asn":
580 if trust is True or purpose.oid in trust:
581 certs.extend(cert)
582 except PermissionError:
583 warnings.warn("unable to enumerate Windows certificate store")
Steve Dower8dd7aeb2016-03-17 15:02:39 -0700584 if certs:
585 self.load_verify_locations(cadata=certs)
Christian Heimes72d28502013-11-23 13:56:58 +0100586 return certs
587
588 def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
589 if not isinstance(purpose, _ASN1Object):
590 raise TypeError(purpose)
591 if sys.platform == "win32":
592 for storename in self._windows_cert_stores:
593 self._load_windows_store_certs(storename, purpose)
Benjamin Peterson5915b0f2014-10-03 17:27:05 -0400594 self.set_default_verify_paths()
Christian Heimes72d28502013-11-23 13:56:58 +0100595
Christian Heimes698dde12018-02-27 11:54:43 +0100596 if hasattr(_SSLContext, 'minimum_version'):
597 @property
598 def minimum_version(self):
599 return TLSVersion(super().minimum_version)
600
601 @minimum_version.setter
602 def minimum_version(self, value):
603 if value == TLSVersion.SSLv3:
604 self.options &= ~Options.OP_NO_SSLv3
605 super(SSLContext, SSLContext).minimum_version.__set__(self, value)
606
607 @property
608 def maximum_version(self):
609 return TLSVersion(super().maximum_version)
610
611 @maximum_version.setter
612 def maximum_version(self, value):
613 super(SSLContext, SSLContext).maximum_version.__set__(self, value)
614
Christian Heimes3aeacad2016-09-10 00:19:35 +0200615 @property
616 def options(self):
617 return Options(super().options)
618
619 @options.setter
620 def options(self, value):
621 super(SSLContext, SSLContext).options.__set__(self, value)
622
Christian Heimes61d478c2018-01-27 15:51:38 +0100623 if hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT'):
624 @property
625 def hostname_checks_common_name(self):
626 ncs = self._host_flags & _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
627 return ncs != _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
628
629 @hostname_checks_common_name.setter
630 def hostname_checks_common_name(self, value):
631 if value:
632 self._host_flags &= ~_ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
633 else:
634 self._host_flags |= _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
635 else:
636 @property
637 def hostname_checks_common_name(self):
638 return True
639
Christian Heimes3aeacad2016-09-10 00:19:35 +0200640 @property
Christian Heimesc7f70692019-05-31 11:44:05 +0200641 def _msg_callback(self):
642 """TLS message callback
643
644 The message callback provides a debugging hook to analyze TLS
645 connections. The callback is called for any TLS protocol message
646 (header, handshake, alert, and more), but not for application data.
647 Due to technical limitations, the callback can't be used to filter
648 traffic or to abort a connection. Any exception raised in the
649 callback is delayed until the handshake, read, or write operation
650 has been performed.
651
652 def msg_cb(conn, direction, version, content_type, msg_type, data):
653 pass
654
655 conn
656 :class:`SSLSocket` or :class:`SSLObject` instance
657 direction
658 ``read`` or ``write``
659 version
660 :class:`TLSVersion` enum member or int for unknown version. For a
661 frame header, it's the header version.
662 content_type
663 :class:`_TLSContentType` enum member or int for unsupported
664 content type.
665 msg_type
666 Either a :class:`_TLSContentType` enum number for a header
667 message, a :class:`_TLSAlertType` enum member for an alert
668 message, a :class:`_TLSMessageType` enum member for other
669 messages, or int for unsupported message types.
670 data
671 Raw, decrypted message content as bytes
672 """
673 inner = super()._msg_callback
674 if inner is not None:
675 return inner.user_function
676 else:
677 return None
678
679 @_msg_callback.setter
680 def _msg_callback(self, callback):
681 if callback is None:
682 super(SSLContext, SSLContext)._msg_callback.__set__(self, None)
683 return
684
685 if not hasattr(callback, '__call__'):
686 raise TypeError(f"{callback} is not callable.")
687
688 def inner(conn, direction, version, content_type, msg_type, data):
689 try:
690 version = TLSVersion(version)
Christian Heimese35d1ba2019-06-03 20:40:15 +0200691 except ValueError:
Christian Heimesc7f70692019-05-31 11:44:05 +0200692 pass
693
694 try:
695 content_type = _TLSContentType(content_type)
Christian Heimese35d1ba2019-06-03 20:40:15 +0200696 except ValueError:
Christian Heimesc7f70692019-05-31 11:44:05 +0200697 pass
698
699 if content_type == _TLSContentType.HEADER:
700 msg_enum = _TLSContentType
701 elif content_type == _TLSContentType.ALERT:
702 msg_enum = _TLSAlertType
703 else:
704 msg_enum = _TLSMessageType
705 try:
706 msg_type = msg_enum(msg_type)
Christian Heimese35d1ba2019-06-03 20:40:15 +0200707 except ValueError:
Christian Heimesc7f70692019-05-31 11:44:05 +0200708 pass
709
710 return callback(conn, direction, version,
711 content_type, msg_type, data)
712
713 inner.user_function = callback
714
715 super(SSLContext, SSLContext)._msg_callback.__set__(self, inner)
716
717 @property
Christian Heimes11a14932018-02-24 02:35:08 +0100718 def protocol(self):
719 return _SSLMethod(super().protocol)
720
721 @property
Christian Heimes3aeacad2016-09-10 00:19:35 +0200722 def verify_flags(self):
723 return VerifyFlags(super().verify_flags)
724
725 @verify_flags.setter
726 def verify_flags(self, value):
727 super(SSLContext, SSLContext).verify_flags.__set__(self, value)
728
729 @property
730 def verify_mode(self):
731 value = super().verify_mode
732 try:
733 return VerifyMode(value)
734 except ValueError:
735 return value
736
737 @verify_mode.setter
738 def verify_mode(self, value):
739 super(SSLContext, SSLContext).verify_mode.__set__(self, value)
740
Antoine Pitrou152efa22010-05-16 18:19:27 +0000741
Christian Heimes4c05b472013-11-23 15:58:30 +0100742def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
743 capath=None, cadata=None):
744 """Create a SSLContext object with default settings.
745
746 NOTE: The protocol and settings may change anytime without prior
747 deprecation. The values represent a fair balance between maximum
748 compatibility and security.
749 """
750 if not isinstance(purpose, _ASN1Object):
751 raise TypeError(purpose)
Donald Stufft6a2ba942014-03-23 19:05:28 -0400752
Christian Heimes358cfd42016-09-10 22:43:48 +0200753 # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
754 # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
755 # by default.
Christian Heimes4c05b472013-11-23 15:58:30 +0100756 if purpose == Purpose.SERVER_AUTH:
Donald Stufft6a2ba942014-03-23 19:05:28 -0400757 # verify certs and host name in client mode
Christian Heimes2875c602021-04-19 07:27:10 +0200758 context = SSLContext(PROTOCOL_TLS_CLIENT)
Christian Heimes4c05b472013-11-23 15:58:30 +0100759 context.verify_mode = CERT_REQUIRED
Christian Heimes1aa9a752013-12-02 02:41:19 +0100760 context.check_hostname = True
Christian Heimes2875c602021-04-19 07:27:10 +0200761 elif purpose == Purpose.CLIENT_AUTH:
762 context = SSLContext(PROTOCOL_TLS_SERVER)
763 else:
764 raise ValueError(purpose)
Donald Stufft6a2ba942014-03-23 19:05:28 -0400765
Christian Heimes4c05b472013-11-23 15:58:30 +0100766 if cafile or capath or cadata:
767 context.load_verify_locations(cafile, capath, cadata)
768 elif context.verify_mode != CERT_NONE:
769 # no explicit cafile, capath or cadata but the verify mode is
770 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
771 # root CA certificates for the given purpose. This may fail silently.
772 context.load_default_certs(purpose)
Christian Heimesc7f70692019-05-31 11:44:05 +0200773 # OpenSSL 1.1.1 keylog file
774 if hasattr(context, 'keylog_filename'):
775 keylogfile = os.environ.get('SSLKEYLOGFILE')
776 if keylogfile and not sys.flags.ignore_environment:
777 context.keylog_filename = keylogfile
Christian Heimes4c05b472013-11-23 15:58:30 +0100778 return context
779
Christian Heimes2875c602021-04-19 07:27:10 +0200780def _create_unverified_context(protocol=None, *, cert_reqs=CERT_NONE,
Christian Heimesa02c69a2013-12-02 20:59:28 +0100781 check_hostname=False, purpose=Purpose.SERVER_AUTH,
Christian Heimes67986f92013-11-23 22:43:47 +0100782 certfile=None, keyfile=None,
783 cafile=None, capath=None, cadata=None):
784 """Create a SSLContext object for Python stdlib modules
785
786 All Python stdlib modules shall use this function to create SSLContext
787 objects in order to keep common settings in one place. The configuration
788 is less restrict than create_default_context()'s to increase backward
789 compatibility.
790 """
791 if not isinstance(purpose, _ASN1Object):
792 raise TypeError(purpose)
793
Christian Heimes358cfd42016-09-10 22:43:48 +0200794 # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
795 # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
796 # by default.
Christian Heimes2875c602021-04-19 07:27:10 +0200797 if purpose == Purpose.SERVER_AUTH:
798 # verify certs and host name in client mode
799 if protocol is None:
800 protocol = PROTOCOL_TLS_CLIENT
801 elif purpose == Purpose.CLIENT_AUTH:
802 if protocol is None:
803 protocol = PROTOCOL_TLS_SERVER
804 else:
805 raise ValueError(purpose)
Christian Heimes67986f92013-11-23 22:43:47 +0100806
Christian Heimes2875c602021-04-19 07:27:10 +0200807 context = SSLContext(protocol)
808 context.check_hostname = check_hostname
Christian Heimes67986f92013-11-23 22:43:47 +0100809 if cert_reqs is not None:
810 context.verify_mode = cert_reqs
Christian Heimesa170fa12017-09-15 20:27:30 +0200811 if check_hostname:
812 context.check_hostname = True
Christian Heimes67986f92013-11-23 22:43:47 +0100813
814 if keyfile and not certfile:
815 raise ValueError("certfile must be specified")
816 if certfile or keyfile:
817 context.load_cert_chain(certfile, keyfile)
818
819 # load CA root certs
820 if cafile or capath or cadata:
821 context.load_verify_locations(cafile, capath, cadata)
822 elif context.verify_mode != CERT_NONE:
823 # no explicit cafile, capath or cadata but the verify mode is
824 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
825 # root CA certificates for the given purpose. This may fail silently.
826 context.load_default_certs(purpose)
Christian Heimesc7f70692019-05-31 11:44:05 +0200827 # OpenSSL 1.1.1 keylog file
828 if hasattr(context, 'keylog_filename'):
829 keylogfile = os.environ.get('SSLKEYLOGFILE')
830 if keylogfile and not sys.flags.ignore_environment:
831 context.keylog_filename = keylogfile
Christian Heimes67986f92013-11-23 22:43:47 +0100832 return context
833
Benjamin Peterson4ffb0752014-11-03 14:29:33 -0500834# Used by http.client if no context is explicitly passed.
835_create_default_https_context = create_default_context
836
837
838# Backwards compatibility alias, even though it's not a public name.
839_create_stdlib_context = _create_unverified_context
840
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200841
842class SSLObject:
843 """This class implements an interface on top of a low-level SSL object as
844 implemented by OpenSSL. This object captures the state of an SSL connection
845 but does not provide any network IO itself. IO needs to be performed
846 through separate "BIO" objects which are OpenSSL's IO abstraction layer.
847
848 This class does not have a public constructor. Instances are returned by
849 ``SSLContext.wrap_bio``. This class is typically used by framework authors
850 that want to implement asynchronous IO for SSL through memory buffers.
851
852 When compared to ``SSLSocket``, this object lacks the following features:
853
Matt Eatonfc7d1b32018-10-05 02:00:45 -0500854 * Any form of network IO, including methods such as ``recv`` and ``send``.
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200855 * The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery.
856 """
Christian Heimes9d50ab52018-02-27 10:17:30 +0100857 def __init__(self, *args, **kwargs):
858 raise TypeError(
859 f"{self.__class__.__name__} does not have a public "
860 f"constructor. Instances are returned by SSLContext.wrap_bio()."
861 )
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200862
Christian Heimes9d50ab52018-02-27 10:17:30 +0100863 @classmethod
864 def _create(cls, incoming, outgoing, server_side=False,
865 server_hostname=None, session=None, context=None):
866 self = cls.__new__(cls)
867 sslobj = context._wrap_bio(
Christian Heimes141c5e82018-02-24 21:10:57 +0100868 incoming, outgoing, server_side=server_side,
869 server_hostname=server_hostname,
870 owner=self, session=session
871 )
Christian Heimes9d50ab52018-02-27 10:17:30 +0100872 self._sslobj = sslobj
873 return self
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200874
875 @property
876 def context(self):
877 """The SSLContext that is currently in use."""
878 return self._sslobj.context
879
880 @context.setter
881 def context(self, ctx):
882 self._sslobj.context = ctx
883
884 @property
Christian Heimes99a65702016-09-10 23:44:53 +0200885 def session(self):
886 """The SSLSession for client socket."""
887 return self._sslobj.session
888
889 @session.setter
890 def session(self, session):
891 self._sslobj.session = session
892
893 @property
894 def session_reused(self):
895 """Was the client session reused during handshake"""
896 return self._sslobj.session_reused
897
898 @property
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200899 def server_side(self):
900 """Whether this is a server-side socket."""
901 return self._sslobj.server_side
902
903 @property
904 def server_hostname(self):
905 """The currently set server hostname (for SNI), or ``None`` if no
Xtreak0d702272019-06-03 04:42:33 +0530906 server hostname is set."""
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200907 return self._sslobj.server_hostname
908
Martin Panterf6b1d662016-03-28 00:22:09 +0000909 def read(self, len=1024, buffer=None):
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200910 """Read up to 'len' bytes from the SSL object and return them.
911
912 If 'buffer' is provided, read into this buffer and return the number of
913 bytes read.
914 """
915 if buffer is not None:
916 v = self._sslobj.read(len, buffer)
917 else:
Martin Panterf6b1d662016-03-28 00:22:09 +0000918 v = self._sslobj.read(len)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200919 return v
920
921 def write(self, data):
922 """Write 'data' to the SSL object and return the number of bytes
923 written.
924
925 The 'data' argument must support the buffer interface.
926 """
927 return self._sslobj.write(data)
928
929 def getpeercert(self, binary_form=False):
930 """Returns a formatted version of the data in the certificate provided
931 by the other end of the SSL channel.
932
933 Return None if no certificate was provided, {} if a certificate was
934 provided, but not validated.
935 """
Christian Heimes141c5e82018-02-24 21:10:57 +0100936 return self._sslobj.getpeercert(binary_form)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200937
938 def selected_npn_protocol(self):
939 """Return the currently selected NPN protocol as a string, or ``None``
940 if a next protocol was not negotiated or if NPN is not supported by one
941 of the peers."""
Christian Heimes2875c602021-04-19 07:27:10 +0200942 warnings.warn(
943 "ssl module: NPN is deprecated, use ALPN instead", stacklevel=2
944 )
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200945
Benjamin Petersoncca27322015-01-23 16:35:37 -0500946 def selected_alpn_protocol(self):
947 """Return the currently selected ALPN protocol as a string, or ``None``
948 if a next protocol was not negotiated or if ALPN is not supported by one
949 of the peers."""
Christian Heimes39258d32021-04-17 11:36:35 +0200950 return self._sslobj.selected_alpn_protocol()
Benjamin Petersoncca27322015-01-23 16:35:37 -0500951
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200952 def cipher(self):
953 """Return the currently selected cipher as a 3-tuple ``(name,
954 ssl_version, secret_bits)``."""
955 return self._sslobj.cipher()
956
Benjamin Peterson4cb17812015-01-07 11:14:26 -0600957 def shared_ciphers(self):
Benjamin Petersonc114e7d2015-01-11 15:22:07 -0500958 """Return a list of ciphers shared by the client during the handshake or
959 None if this is not a valid server connection.
Benjamin Peterson5318c7a2015-01-07 11:26:50 -0600960 """
Benjamin Peterson4cb17812015-01-07 11:14:26 -0600961 return self._sslobj.shared_ciphers()
962
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200963 def compression(self):
964 """Return the current compression algorithm in use, or ``None`` if
965 compression was not negotiated or not supported by one of the peers."""
966 return self._sslobj.compression()
967
968 def pending(self):
969 """Return the number of bytes that can be read immediately."""
970 return self._sslobj.pending()
971
Antoine Pitrou3cb93792014-10-06 00:21:09 +0200972 def do_handshake(self):
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200973 """Start the SSL/TLS handshake."""
974 self._sslobj.do_handshake()
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200975
976 def unwrap(self):
977 """Start the SSL shutdown handshake."""
978 return self._sslobj.shutdown()
979
980 def get_channel_binding(self, cb_type="tls-unique"):
981 """Get channel binding data for current connection. Raise ValueError
982 if the requested `cb_type` is not supported. Return bytes of the data
983 or None if the data is not available (e.g. before the handshake)."""
Christian Heimes141c5e82018-02-24 21:10:57 +0100984 return self._sslobj.get_channel_binding(cb_type)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200985
986 def version(self):
987 """Return a string identifying the protocol version used by the
988 current SSL channel. """
989 return self._sslobj.version()
990
Christian Heimes9fb051f2018-09-23 08:32:31 +0200991 def verify_client_post_handshake(self):
992 return self._sslobj.verify_client_post_handshake()
993
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200994
Christian Heimes80ed3532019-05-17 13:08:14 +0200995def _sslcopydoc(func):
996 """Copy docstring from SSLObject to SSLSocket"""
997 func.__doc__ = getattr(SSLObject, func.__name__).__doc__
998 return func
999
1000
Antoine Pitrou152efa22010-05-16 18:19:27 +00001001class SSLSocket(socket):
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001002 """This class implements a subtype of socket.socket that wraps
1003 the underlying OS socket in an SSL context when necessary, and
Christian Heimes9d50ab52018-02-27 10:17:30 +01001004 provides read and write methods over that channel. """
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001005
Christian Heimes9d50ab52018-02-27 10:17:30 +01001006 def __init__(self, *args, **kwargs):
1007 raise TypeError(
1008 f"{self.__class__.__name__} does not have a public "
1009 f"constructor. Instances are returned by "
1010 f"SSLContext.wrap_socket()."
1011 )
Bill Janssen6e027db2007-11-15 22:23:56 +00001012
Christian Heimes9d50ab52018-02-27 10:17:30 +01001013 @classmethod
1014 def _create(cls, sock, server_side=False, do_handshake_on_connect=True,
1015 suppress_ragged_eofs=True, server_hostname=None,
1016 context=None, session=None):
Antoine Pitrou3e86ba42013-12-28 17:26:33 +01001017 if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
1018 raise NotImplementedError("only stream sockets are supported")
Christian Heimes99a65702016-09-10 23:44:53 +02001019 if server_side:
1020 if server_hostname:
1021 raise ValueError("server_hostname can only be specified "
1022 "in client mode")
Christian Heimes9d50ab52018-02-27 10:17:30 +01001023 if session is not None:
Christian Heimes99a65702016-09-10 23:44:53 +02001024 raise ValueError("session can only be specified in "
1025 "client mode")
Christian Heimes9d50ab52018-02-27 10:17:30 +01001026 if context.check_hostname and not server_hostname:
Benjamin Peterson7243b572014-11-23 17:04:34 -06001027 raise ValueError("check_hostname requires server_hostname")
Christian Heimes9d50ab52018-02-27 10:17:30 +01001028
1029 kwargs = dict(
1030 family=sock.family, type=sock.type, proto=sock.proto,
1031 fileno=sock.fileno()
1032 )
1033 self = cls.__new__(cls, **kwargs)
1034 super(SSLSocket, self).__init__(**kwargs)
1035 self.settimeout(sock.gettimeout())
1036 sock.detach()
1037
1038 self._context = context
1039 self._session = session
1040 self._closed = False
1041 self._sslobj = None
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001042 self.server_side = server_side
Christian Heimes9d50ab52018-02-27 10:17:30 +01001043 self.server_hostname = context._encode_hostname(server_hostname)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001044 self.do_handshake_on_connect = do_handshake_on_connect
1045 self.suppress_ragged_eofs = suppress_ragged_eofs
Bill Janssen6e027db2007-11-15 22:23:56 +00001046
Antoine Pitrou242db722013-05-01 20:52:07 +02001047 # See if we are connected
1048 try:
1049 self.getpeername()
1050 except OSError as e:
1051 if e.errno != errno.ENOTCONN:
1052 raise
1053 connected = False
1054 else:
1055 connected = True
1056
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001057 self._connected = connected
Antoine Pitroufa2b9382010-04-26 22:17:47 +00001058 if connected:
1059 # create the SSL object
Bill Janssen6e027db2007-11-15 22:23:56 +00001060 try:
Christian Heimes141c5e82018-02-24 21:10:57 +01001061 self._sslobj = self._context._wrap_socket(
1062 self, server_side, self.server_hostname,
1063 owner=self, session=self._session,
1064 )
Bill Janssen6e027db2007-11-15 22:23:56 +00001065 if do_handshake_on_connect:
Bill Janssen48dc27c2007-12-05 03:38:10 +00001066 timeout = self.gettimeout()
1067 if timeout == 0.0:
1068 # non-blocking
1069 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
Bill Janssen6e027db2007-11-15 22:23:56 +00001070 self.do_handshake()
Christian Heimes1aa9a752013-12-02 02:41:19 +01001071 except (OSError, ValueError):
Bill Janssen6e027db2007-11-15 22:23:56 +00001072 self.close()
Christian Heimes1aa9a752013-12-02 02:41:19 +01001073 raise
Christian Heimes9d50ab52018-02-27 10:17:30 +01001074 return self
Antoine Pitrou242db722013-05-01 20:52:07 +02001075
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001076 @property
Christian Heimes80ed3532019-05-17 13:08:14 +02001077 @_sslcopydoc
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001078 def context(self):
1079 return self._context
1080
1081 @context.setter
1082 def context(self, ctx):
1083 self._context = ctx
1084 self._sslobj.context = ctx
Bill Janssen6e027db2007-11-15 22:23:56 +00001085
Christian Heimes99a65702016-09-10 23:44:53 +02001086 @property
Christian Heimes80ed3532019-05-17 13:08:14 +02001087 @_sslcopydoc
Christian Heimes99a65702016-09-10 23:44:53 +02001088 def session(self):
Christian Heimes99a65702016-09-10 23:44:53 +02001089 if self._sslobj is not None:
1090 return self._sslobj.session
1091
1092 @session.setter
1093 def session(self, session):
1094 self._session = session
1095 if self._sslobj is not None:
1096 self._sslobj.session = session
1097
1098 @property
Christian Heimes80ed3532019-05-17 13:08:14 +02001099 @_sslcopydoc
Christian Heimes99a65702016-09-10 23:44:53 +02001100 def session_reused(self):
Christian Heimes99a65702016-09-10 23:44:53 +02001101 if self._sslobj is not None:
1102 return self._sslobj.session_reused
1103
Guido van Rossumb7b030e2007-11-16 01:28:45 +00001104 def dup(self):
Serhiy Storchaka42b1d612018-12-06 22:36:55 +02001105 raise NotImplementedError("Can't dup() %s instances" %
1106 self.__class__.__name__)
Guido van Rossumb7b030e2007-11-16 01:28:45 +00001107
Bill Janssen6e027db2007-11-15 22:23:56 +00001108 def _checkClosed(self, msg=None):
1109 # raise an exception here if you wish to check for spurious closes
1110 pass
1111
Antoine Pitrou242db722013-05-01 20:52:07 +02001112 def _check_connected(self):
1113 if not self._connected:
1114 # getpeername() will raise ENOTCONN if the socket is really
1115 # not connected; note that we can be connected even without
1116 # _connected being set, e.g. if connect() first returned
1117 # EAGAIN.
1118 self.getpeername()
1119
Martin Panterf6b1d662016-03-28 00:22:09 +00001120 def read(self, len=1024, buffer=None):
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001121 """Read up to LEN bytes and return them.
1122 Return zero-length string on EOF."""
1123
Bill Janssen6e027db2007-11-15 22:23:56 +00001124 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001125 if self._sslobj is None:
Antoine Pitrou60a26e02013-07-20 19:35:16 +02001126 raise ValueError("Read on closed or unwrapped SSL socket.")
Bill Janssen6e027db2007-11-15 22:23:56 +00001127 try:
Christian Heimes141c5e82018-02-24 21:10:57 +01001128 if buffer is not None:
1129 return self._sslobj.read(len, buffer)
1130 else:
1131 return self._sslobj.read(len)
Bill Janssen6e027db2007-11-15 22:23:56 +00001132 except SSLError as x:
1133 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
Antoine Pitrou24e561a2010-09-03 18:38:17 +00001134 if buffer is not None:
Bill Janssen54cc54c2007-12-14 22:08:56 +00001135 return 0
1136 else:
1137 return b''
Bill Janssen6e027db2007-11-15 22:23:56 +00001138 else:
1139 raise
Thomas Woutersed03b412007-08-28 21:37:11 +00001140
1141 def write(self, data):
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001142 """Write DATA to the underlying SSL channel. Returns
1143 number of bytes of DATA actually transmitted."""
1144
Bill Janssen6e027db2007-11-15 22:23:56 +00001145 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001146 if self._sslobj is None:
Antoine Pitrou60a26e02013-07-20 19:35:16 +02001147 raise ValueError("Write on closed or unwrapped SSL socket.")
Thomas Woutersed03b412007-08-28 21:37:11 +00001148 return self._sslobj.write(data)
1149
Christian Heimes80ed3532019-05-17 13:08:14 +02001150 @_sslcopydoc
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001151 def getpeercert(self, binary_form=False):
Bill Janssen6e027db2007-11-15 22:23:56 +00001152 self._checkClosed()
Antoine Pitrou242db722013-05-01 20:52:07 +02001153 self._check_connected()
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001154 return self._sslobj.getpeercert(binary_form)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001155
Christian Heimes80ed3532019-05-17 13:08:14 +02001156 @_sslcopydoc
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001157 def selected_npn_protocol(self):
1158 self._checkClosed()
Christian Heimes2875c602021-04-19 07:27:10 +02001159 warnings.warn(
1160 "ssl module: NPN is deprecated, use ALPN instead", stacklevel=2
1161 )
Christian Heimes39258d32021-04-17 11:36:35 +02001162 return None
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001163
Christian Heimes80ed3532019-05-17 13:08:14 +02001164 @_sslcopydoc
Benjamin Petersoncca27322015-01-23 16:35:37 -05001165 def selected_alpn_protocol(self):
1166 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001167 if self._sslobj is None or not _ssl.HAS_ALPN:
Benjamin Petersoncca27322015-01-23 16:35:37 -05001168 return None
1169 else:
1170 return self._sslobj.selected_alpn_protocol()
1171
Christian Heimes80ed3532019-05-17 13:08:14 +02001172 @_sslcopydoc
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001173 def cipher(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001174 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001175 if self._sslobj is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001176 return None
1177 else:
1178 return self._sslobj.cipher()
Thomas Woutersed03b412007-08-28 21:37:11 +00001179
Christian Heimes80ed3532019-05-17 13:08:14 +02001180 @_sslcopydoc
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001181 def shared_ciphers(self):
1182 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001183 if self._sslobj is None:
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001184 return None
Christian Heimes141c5e82018-02-24 21:10:57 +01001185 else:
1186 return self._sslobj.shared_ciphers()
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001187
Christian Heimes80ed3532019-05-17 13:08:14 +02001188 @_sslcopydoc
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01001189 def compression(self):
1190 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001191 if self._sslobj is None:
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01001192 return None
1193 else:
1194 return self._sslobj.compression()
1195
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001196 def send(self, data, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001197 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001198 if self._sslobj is not None:
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001199 if flags != 0:
1200 raise ValueError(
1201 "non-zero flags not allowed in calls to send() on %s" %
1202 self.__class__)
Antoine Pitroub4bebda2014-04-29 10:03:28 +02001203 return self._sslobj.write(data)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001204 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001205 return super().send(data, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001206
Antoine Pitroua468adc2010-09-14 14:43:44 +00001207 def sendto(self, data, flags_or_addr, addr=None):
Bill Janssen6e027db2007-11-15 22:23:56 +00001208 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001209 if self._sslobj is not None:
Bill Janssen980f3142008-06-29 00:05:51 +00001210 raise ValueError("sendto not allowed on instances of %s" %
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001211 self.__class__)
Antoine Pitroua468adc2010-09-14 14:43:44 +00001212 elif addr is None:
Mads Jensen746cc752018-01-27 13:34:28 +01001213 return super().sendto(data, flags_or_addr)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001214 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001215 return super().sendto(data, flags_or_addr, addr)
Thomas Woutersed03b412007-08-28 21:37:11 +00001216
Nick Coghlan513886a2011-08-28 00:00:27 +10001217 def sendmsg(self, *args, **kwargs):
1218 # Ensure programs don't send data unencrypted if they try to
1219 # use this method.
1220 raise NotImplementedError("sendmsg not allowed on instances of %s" %
1221 self.__class__)
1222
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001223 def sendall(self, data, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001224 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001225 if self._sslobj is not None:
Giampaolo Rodolà374f8352010-08-29 12:08:09 +00001226 if flags != 0:
1227 raise ValueError(
1228 "non-zero flags not allowed in calls to sendall() on %s" %
1229 self.__class__)
Bill Janssen6e027db2007-11-15 22:23:56 +00001230 count = 0
Christian Heimes888bbdc2017-09-07 14:18:21 -07001231 with memoryview(data) as view, view.cast("B") as byte_view:
1232 amount = len(byte_view)
1233 while count < amount:
1234 v = self.send(byte_view[count:])
1235 count += v
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001236 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001237 return super().sendall(data, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001238
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02001239 def sendfile(self, file, offset=0, count=None):
1240 """Send a file, possibly by using os.sendfile() if this is a
1241 clear-text socket. Return the total number of bytes sent.
1242 """
Christian Heimes141c5e82018-02-24 21:10:57 +01001243 if self._sslobj is not None:
1244 return self._sendfile_use_send(file, offset, count)
1245 else:
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02001246 # os.sendfile() works with plain sockets only
1247 return super().sendfile(file, offset, count)
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02001248
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001249 def recv(self, buflen=1024, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001250 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001251 if self._sslobj is not None:
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001252 if flags != 0:
1253 raise ValueError(
Antoine Pitrou5733c082010-03-22 14:49:10 +00001254 "non-zero flags not allowed in calls to recv() on %s" %
1255 self.__class__)
1256 return self.read(buflen)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001257 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001258 return super().recv(buflen, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001259
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001260 def recv_into(self, buffer, nbytes=None, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001261 self._checkClosed()
1262 if buffer and (nbytes is None):
1263 nbytes = len(buffer)
1264 elif nbytes is None:
1265 nbytes = 1024
Christian Heimes141c5e82018-02-24 21:10:57 +01001266 if self._sslobj is not None:
Bill Janssen6e027db2007-11-15 22:23:56 +00001267 if flags != 0:
1268 raise ValueError(
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001269 "non-zero flags not allowed in calls to recv_into() on %s" %
1270 self.__class__)
Antoine Pitrou5733c082010-03-22 14:49:10 +00001271 return self.read(nbytes, buffer)
Bill Janssen6e027db2007-11-15 22:23:56 +00001272 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001273 return super().recv_into(buffer, nbytes, flags)
Bill Janssen6e027db2007-11-15 22:23:56 +00001274
Antoine Pitroua468adc2010-09-14 14:43:44 +00001275 def recvfrom(self, buflen=1024, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001276 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001277 if self._sslobj is not None:
Bill Janssen980f3142008-06-29 00:05:51 +00001278 raise ValueError("recvfrom not allowed on instances of %s" %
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001279 self.__class__)
1280 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001281 return super().recvfrom(buflen, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001282
Bill Janssen58afe4c2008-09-08 16:45:19 +00001283 def recvfrom_into(self, buffer, nbytes=None, flags=0):
1284 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001285 if self._sslobj is not None:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001286 raise ValueError("recvfrom_into not allowed on instances of %s" %
1287 self.__class__)
1288 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001289 return super().recvfrom_into(buffer, nbytes, flags)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001290
Nick Coghlan513886a2011-08-28 00:00:27 +10001291 def recvmsg(self, *args, **kwargs):
1292 raise NotImplementedError("recvmsg not allowed on instances of %s" %
1293 self.__class__)
1294
1295 def recvmsg_into(self, *args, **kwargs):
1296 raise NotImplementedError("recvmsg_into not allowed on instances of "
1297 "%s" % self.__class__)
1298
Christian Heimes80ed3532019-05-17 13:08:14 +02001299 @_sslcopydoc
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001300 def pending(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001301 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001302 if self._sslobj is not None:
Bill Janssen6e027db2007-11-15 22:23:56 +00001303 return self._sslobj.pending()
1304 else:
1305 return 0
1306
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001307 def shutdown(self, how):
Bill Janssen6e027db2007-11-15 22:23:56 +00001308 self._checkClosed()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001309 self._sslobj = None
Mads Jensen746cc752018-01-27 13:34:28 +01001310 super().shutdown(how)
Thomas Woutersed03b412007-08-28 21:37:11 +00001311
Christian Heimes80ed3532019-05-17 13:08:14 +02001312 @_sslcopydoc
Ezio Melottidc55e672010-01-18 09:15:14 +00001313 def unwrap(self):
Bill Janssen40a0f662008-08-12 16:56:25 +00001314 if self._sslobj:
Christian Heimes141c5e82018-02-24 21:10:57 +01001315 s = self._sslobj.shutdown()
Bill Janssen40a0f662008-08-12 16:56:25 +00001316 self._sslobj = None
1317 return s
1318 else:
1319 raise ValueError("No SSL wrapper around " + str(self))
1320
Christian Heimes80ed3532019-05-17 13:08:14 +02001321 @_sslcopydoc
Christian Heimes9fb051f2018-09-23 08:32:31 +02001322 def verify_client_post_handshake(self):
1323 if self._sslobj:
1324 return self._sslobj.verify_client_post_handshake()
1325 else:
1326 raise ValueError("No SSL wrapper around " + str(self))
1327
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001328 def _real_close(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001329 self._sslobj = None
Mads Jensen746cc752018-01-27 13:34:28 +01001330 super()._real_close()
Bill Janssen6e027db2007-11-15 22:23:56 +00001331
Christian Heimes80ed3532019-05-17 13:08:14 +02001332 @_sslcopydoc
Bill Janssen48dc27c2007-12-05 03:38:10 +00001333 def do_handshake(self, block=False):
Antoine Pitrou242db722013-05-01 20:52:07 +02001334 self._check_connected()
Bill Janssen48dc27c2007-12-05 03:38:10 +00001335 timeout = self.gettimeout()
Bill Janssen6e027db2007-11-15 22:23:56 +00001336 try:
Bill Janssen48dc27c2007-12-05 03:38:10 +00001337 if timeout == 0.0 and block:
1338 self.settimeout(None)
Bill Janssen6e027db2007-11-15 22:23:56 +00001339 self._sslobj.do_handshake()
Bill Janssen48dc27c2007-12-05 03:38:10 +00001340 finally:
1341 self.settimeout(timeout)
Thomas Woutersed03b412007-08-28 21:37:11 +00001342
Antoine Pitroub4410db2011-05-18 18:51:06 +02001343 def _real_connect(self, addr, connect_ex):
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001344 if self.server_side:
1345 raise ValueError("can't connect in server-side mode")
Thomas Woutersed03b412007-08-28 21:37:11 +00001346 # Here we assume that the socket is client-side, and not
1347 # connected at the time of the call. We connect it, then wrap it.
Christian Heimes141c5e82018-02-24 21:10:57 +01001348 if self._connected or self._sslobj is not None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001349 raise ValueError("attempt to connect already-connected SSLSocket!")
Christian Heimes141c5e82018-02-24 21:10:57 +01001350 self._sslobj = self.context._wrap_socket(
1351 self, False, self.server_hostname,
1352 owner=self, session=self._session
1353 )
Bill Janssen54cc54c2007-12-14 22:08:56 +00001354 try:
Antoine Pitroub4410db2011-05-18 18:51:06 +02001355 if connect_ex:
Mads Jensen746cc752018-01-27 13:34:28 +01001356 rc = super().connect_ex(addr)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001357 else:
Antoine Pitroub4410db2011-05-18 18:51:06 +02001358 rc = None
Mads Jensen746cc752018-01-27 13:34:28 +01001359 super().connect(addr)
Antoine Pitroub4410db2011-05-18 18:51:06 +02001360 if not rc:
Antoine Pitrou242db722013-05-01 20:52:07 +02001361 self._connected = True
Antoine Pitroub4410db2011-05-18 18:51:06 +02001362 if self.do_handshake_on_connect:
1363 self.do_handshake()
Antoine Pitroub4410db2011-05-18 18:51:06 +02001364 return rc
Christian Heimes1aa9a752013-12-02 02:41:19 +01001365 except (OSError, ValueError):
Antoine Pitroub4410db2011-05-18 18:51:06 +02001366 self._sslobj = None
1367 raise
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001368
1369 def connect(self, addr):
1370 """Connects to remote ADDR, and then wraps the connection in
1371 an SSL channel."""
1372 self._real_connect(addr, False)
1373
1374 def connect_ex(self, addr):
1375 """Connects to remote ADDR, and then wraps the connection in
1376 an SSL channel."""
1377 return self._real_connect(addr, True)
Thomas Woutersed03b412007-08-28 21:37:11 +00001378
1379 def accept(self):
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001380 """Accepts a new connection from a remote client, and returns
1381 a tuple containing that new connection wrapped with a server-side
1382 SSL channel, and the address of the remote client."""
1383
Mads Jensen746cc752018-01-27 13:34:28 +01001384 newsock, addr = super().accept()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01001385 newsock = self.context.wrap_socket(newsock,
1386 do_handshake_on_connect=self.do_handshake_on_connect,
1387 suppress_ragged_eofs=self.suppress_ragged_eofs,
1388 server_side=True)
1389 return newsock, addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001390
Christian Heimes80ed3532019-05-17 13:08:14 +02001391 @_sslcopydoc
Antoine Pitroud6494802011-07-21 01:11:30 +02001392 def get_channel_binding(self, cb_type="tls-unique"):
Christian Heimes141c5e82018-02-24 21:10:57 +01001393 if self._sslobj is not None:
1394 return self._sslobj.get_channel_binding(cb_type)
1395 else:
1396 if cb_type not in CHANNEL_BINDING_TYPES:
1397 raise ValueError(
1398 "{0} channel binding type not implemented".format(cb_type)
1399 )
Antoine Pitroud6494802011-07-21 01:11:30 +02001400 return None
Antoine Pitroud6494802011-07-21 01:11:30 +02001401
Christian Heimes80ed3532019-05-17 13:08:14 +02001402 @_sslcopydoc
Antoine Pitrou47e40422014-09-04 21:00:10 +02001403 def version(self):
Christian Heimes141c5e82018-02-24 21:10:57 +01001404 if self._sslobj is not None:
1405 return self._sslobj.version()
1406 else:
Antoine Pitrou47e40422014-09-04 21:00:10 +02001407 return None
Antoine Pitrou47e40422014-09-04 21:00:10 +02001408
Bill Janssen54cc54c2007-12-14 22:08:56 +00001409
Christian Heimes4df60f12017-09-15 20:26:05 +02001410# Python does not support forward declaration of types.
1411SSLContext.sslsocket_class = SSLSocket
1412SSLContext.sslobject_class = SSLObject
1413
1414
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001415def wrap_socket(sock, keyfile=None, certfile=None,
1416 server_side=False, cert_reqs=CERT_NONE,
Christian Heimes598894f2016-09-05 23:19:05 +02001417 ssl_version=PROTOCOL_TLS, ca_certs=None,
Bill Janssen48dc27c2007-12-05 03:38:10 +00001418 do_handshake_on_connect=True,
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001419 suppress_ragged_eofs=True,
1420 ciphers=None):
Christian Heimes2875c602021-04-19 07:27:10 +02001421 warnings.warn(
1422 "ssl module: wrap_socket is deprecated, use SSLContext.wrap_socket()",
1423 category=DeprecationWarning,
1424 stacklevel=2
1425 )
Christian Heimes9d50ab52018-02-27 10:17:30 +01001426 if server_side and not certfile:
1427 raise ValueError("certfile must be specified for server-side "
1428 "operations")
1429 if keyfile and not certfile:
1430 raise ValueError("certfile must be specified")
1431 context = SSLContext(ssl_version)
1432 context.verify_mode = cert_reqs
1433 if ca_certs:
1434 context.load_verify_locations(ca_certs)
1435 if certfile:
1436 context.load_cert_chain(certfile, keyfile)
1437 if ciphers:
1438 context.set_ciphers(ciphers)
1439 return context.wrap_socket(
1440 sock=sock, server_side=server_side,
1441 do_handshake_on_connect=do_handshake_on_connect,
1442 suppress_ragged_eofs=suppress_ragged_eofs
1443 )
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001444
Thomas Woutersed03b412007-08-28 21:37:11 +00001445# some utility functions
1446
1447def cert_time_to_seconds(cert_time):
Antoine Pitrouc695c952014-04-28 20:57:36 +02001448 """Return the time in seconds since the Epoch, given the timestring
1449 representing the "notBefore" or "notAfter" date from a certificate
1450 in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale).
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001451
Antoine Pitrouc695c952014-04-28 20:57:36 +02001452 "notBefore" or "notAfter" dates must use UTC (RFC 5280).
1453
1454 Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1455 UTC should be specified as GMT (see ASN1_TIME_print())
1456 """
1457 from time import strptime
1458 from calendar import timegm
1459
1460 months = (
1461 "Jan","Feb","Mar","Apr","May","Jun",
1462 "Jul","Aug","Sep","Oct","Nov","Dec"
1463 )
1464 time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT
1465 try:
1466 month_number = months.index(cert_time[:3].title()) + 1
1467 except ValueError:
1468 raise ValueError('time data %r does not match '
1469 'format "%%b%s"' % (cert_time, time_format))
1470 else:
1471 # found valid month
1472 tt = strptime(cert_time[3:], time_format)
1473 # return an integer, the previous mktime()-based implementation
1474 # returned a float (fractional seconds are always zero here).
1475 return timegm((tt[0], month_number) + tt[2:6])
Thomas Woutersed03b412007-08-28 21:37:11 +00001476
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001477PEM_HEADER = "-----BEGIN CERTIFICATE-----"
1478PEM_FOOTER = "-----END CERTIFICATE-----"
1479
1480def DER_cert_to_PEM_cert(der_cert_bytes):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001481 """Takes a certificate in binary DER format and returns the
1482 PEM version of it as a string."""
1483
Bill Janssen6e027db2007-11-15 22:23:56 +00001484 f = str(base64.standard_b64encode(der_cert_bytes), 'ASCII', 'strict')
INADA Naokib75a2282017-10-02 16:33:42 +09001485 ss = [PEM_HEADER]
1486 ss += [f[i:i+64] for i in range(0, len(f), 64)]
1487 ss.append(PEM_FOOTER + '\n')
1488 return '\n'.join(ss)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001489
1490def PEM_cert_to_DER_cert(pem_cert_string):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001491 """Takes a certificate in ASCII PEM format and returns the
1492 DER-encoded version of it as a byte sequence"""
1493
1494 if not pem_cert_string.startswith(PEM_HEADER):
1495 raise ValueError("Invalid PEM encoding; must start with %s"
1496 % PEM_HEADER)
1497 if not pem_cert_string.strip().endswith(PEM_FOOTER):
1498 raise ValueError("Invalid PEM encoding; must end with %s"
1499 % PEM_FOOTER)
1500 d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
Georg Brandl706824f2009-06-04 09:42:55 +00001501 return base64.decodebytes(d.encode('ASCII', 'strict'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001502
Christian Heimes2875c602021-04-19 07:27:10 +02001503def get_server_certificate(addr, ssl_version=PROTOCOL_TLS_CLIENT, ca_certs=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001504 """Retrieve the certificate from the server at the specified address,
1505 and return it as a PEM-encoded string.
1506 If 'ca_certs' is specified, validate the server cert against it.
1507 If 'ssl_version' is specified, use it in the connection attempt."""
1508
1509 host, port = addr
Christian Heimes67986f92013-11-23 22:43:47 +01001510 if ca_certs is not None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001511 cert_reqs = CERT_REQUIRED
1512 else:
1513 cert_reqs = CERT_NONE
Christian Heimes67986f92013-11-23 22:43:47 +01001514 context = _create_stdlib_context(ssl_version,
1515 cert_reqs=cert_reqs,
1516 cafile=ca_certs)
1517 with create_connection(addr) as sock:
juhovh49fdf112021-04-18 21:11:48 +10001518 with context.wrap_socket(sock, server_hostname=host) as sslsock:
Christian Heimes67986f92013-11-23 22:43:47 +01001519 dercert = sslsock.getpeercert(True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001520 return DER_cert_to_PEM_cert(dercert)
1521
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001522def get_protocol_name(protocol_code):
Victor Stinner3de49192011-05-09 00:42:58 +02001523 return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')