blob: d631805d6cabe531b08072b0b719d92b3970402c [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
Ethan Furman503cdc72021-04-19 19:12:24 -0700158class TLSVersion(_IntEnum):
Christian Heimes698dde12018-02-27 11:54:43 +0100159 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
Ethan Furman503cdc72021-04-19 19:12:24 -0700168class _TLSContentType(_IntEnum):
Christian Heimesc7f70692019-05-31 11:44:05 +0200169 """Content types (record layer)
170
171 See RFC 8446, section B.1
172 """
173 CHANGE_CIPHER_SPEC = 20
174 ALERT = 21
175 HANDSHAKE = 22
176 APPLICATION_DATA = 23
177 # pseudo content types
178 HEADER = 0x100
179 INNER_CONTENT_TYPE = 0x101
180
181
Ethan Furman503cdc72021-04-19 19:12:24 -0700182class _TLSAlertType(_IntEnum):
Christian Heimesc7f70692019-05-31 11:44:05 +0200183 """Alert types for TLSContentType.ALERT messages
184
185 See RFC 8466, section B.2
186 """
187 CLOSE_NOTIFY = 0
188 UNEXPECTED_MESSAGE = 10
189 BAD_RECORD_MAC = 20
190 DECRYPTION_FAILED = 21
191 RECORD_OVERFLOW = 22
192 DECOMPRESSION_FAILURE = 30
193 HANDSHAKE_FAILURE = 40
194 NO_CERTIFICATE = 41
195 BAD_CERTIFICATE = 42
196 UNSUPPORTED_CERTIFICATE = 43
197 CERTIFICATE_REVOKED = 44
198 CERTIFICATE_EXPIRED = 45
199 CERTIFICATE_UNKNOWN = 46
200 ILLEGAL_PARAMETER = 47
201 UNKNOWN_CA = 48
202 ACCESS_DENIED = 49
203 DECODE_ERROR = 50
204 DECRYPT_ERROR = 51
205 EXPORT_RESTRICTION = 60
206 PROTOCOL_VERSION = 70
207 INSUFFICIENT_SECURITY = 71
208 INTERNAL_ERROR = 80
209 INAPPROPRIATE_FALLBACK = 86
210 USER_CANCELED = 90
211 NO_RENEGOTIATION = 100
212 MISSING_EXTENSION = 109
213 UNSUPPORTED_EXTENSION = 110
214 CERTIFICATE_UNOBTAINABLE = 111
215 UNRECOGNIZED_NAME = 112
216 BAD_CERTIFICATE_STATUS_RESPONSE = 113
217 BAD_CERTIFICATE_HASH_VALUE = 114
218 UNKNOWN_PSK_IDENTITY = 115
219 CERTIFICATE_REQUIRED = 116
220 NO_APPLICATION_PROTOCOL = 120
221
222
Ethan Furman503cdc72021-04-19 19:12:24 -0700223class _TLSMessageType(_IntEnum):
Christian Heimesc7f70692019-05-31 11:44:05 +0200224 """Message types (handshake protocol)
225
226 See RFC 8446, section B.3
227 """
228 HELLO_REQUEST = 0
229 CLIENT_HELLO = 1
230 SERVER_HELLO = 2
231 HELLO_VERIFY_REQUEST = 3
232 NEWSESSION_TICKET = 4
233 END_OF_EARLY_DATA = 5
234 HELLO_RETRY_REQUEST = 6
235 ENCRYPTED_EXTENSIONS = 8
236 CERTIFICATE = 11
237 SERVER_KEY_EXCHANGE = 12
238 CERTIFICATE_REQUEST = 13
239 SERVER_DONE = 14
240 CERTIFICATE_VERIFY = 15
241 CLIENT_KEY_EXCHANGE = 16
242 FINISHED = 20
243 CERTIFICATE_URL = 21
244 CERTIFICATE_STATUS = 22
245 SUPPLEMENTAL_DATA = 23
246 KEY_UPDATE = 24
247 NEXT_PROTO = 67
248 MESSAGE_HASH = 254
249 CHANGE_CIPHER_SPEC = 0x0101
250
251
Christian Heimes46bebee2013-06-09 19:03:31 +0200252if sys.platform == "win32":
Christian Heimes44109d72013-11-22 01:51:30 +0100253 from _ssl import enum_certificates, enum_crls
Christian Heimes46bebee2013-06-09 19:03:31 +0200254
Victor Stinnereb0d3592020-05-01 02:38:00 +0200255from socket import socket, SOCK_STREAM, create_connection
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100256from socket import SOL_SOCKET, SO_TYPE
Christian Heimesaef12832018-02-24 14:35:56 +0100257import socket as _socket
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000258import base64 # for DER-to-PEM translation
Antoine Pitroude8cf322010-04-26 17:29:05 +0000259import errno
Steve Dower33bc4a22016-05-26 12:18:12 -0700260import warnings
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000261
Andrew Svetlov0832af62012-12-18 23:10:48 +0200262
263socket_error = OSError # keep that public name in module namespace
264
Christian Heimes141c5e82018-02-24 21:10:57 +0100265CHANNEL_BINDING_TYPES = ['tls-unique']
Thomas Woutersed03b412007-08-28 21:37:11 +0000266
Christian Heimes61d478c2018-01-27 15:51:38 +0100267HAS_NEVER_CHECK_COMMON_NAME = hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT')
268
Christian Heimes03d13c02016-09-06 20:06:47 +0200269
Christian Heimes892d66e2018-01-29 14:10:18 +0100270_RESTRICTED_SERVER_CIPHERS = _DEFAULT_CIPHERS
Christian Heimes4c05b472013-11-23 15:58:30 +0100271
Christian Heimes61d478c2018-01-27 15:51:38 +0100272CertificateError = SSLCertVerificationError
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000273
274
Mandeep Singhede2ac92017-11-27 04:01:27 +0530275def _dnsname_match(dn, hostname):
Georg Brandl72c98d32013-10-27 07:16:53 +0100276 """Matching according to RFC 6125, section 6.4.3
277
Christian Heimesaef12832018-02-24 14:35:56 +0100278 - Hostnames are compared lower case.
279 - For IDNA, both dn and hostname must be encoded as IDN A-label (ACE).
280 - Partial wildcards like 'www*.example.org', multiple wildcards, sole
281 wildcard or wildcards in labels other then the left-most label are not
282 supported and a CertificateError is raised.
283 - A wildcard must match at least one character.
Georg Brandl72c98d32013-10-27 07:16:53 +0100284 """
Georg Brandl72c98d32013-10-27 07:16:53 +0100285 if not dn:
286 return False
287
Christian Heimesaef12832018-02-24 14:35:56 +0100288 wildcards = dn.count('*')
Georg Brandl72c98d32013-10-27 07:16:53 +0100289 # speed up common case w/o wildcards
290 if not wildcards:
291 return dn.lower() == hostname.lower()
292
Christian Heimesaef12832018-02-24 14:35:56 +0100293 if wildcards > 1:
294 raise CertificateError(
295 "too many wildcards in certificate DNS name: {!r}.".format(dn))
Georg Brandl72c98d32013-10-27 07:16:53 +0100296
Christian Heimesaef12832018-02-24 14:35:56 +0100297 dn_leftmost, sep, dn_remainder = dn.partition('.')
Georg Brandl72c98d32013-10-27 07:16:53 +0100298
Christian Heimesaef12832018-02-24 14:35:56 +0100299 if '*' in dn_remainder:
300 # Only match wildcard in leftmost segment.
301 raise CertificateError(
302 "wildcard can only be present in the leftmost label: "
303 "{!r}.".format(dn))
304
305 if not sep:
306 # no right side
307 raise CertificateError(
308 "sole wildcard without additional labels are not support: "
309 "{!r}.".format(dn))
310
311 if dn_leftmost != '*':
312 # no partial wildcard matching
313 raise CertificateError(
314 "partial wildcards in leftmost label are not supported: "
315 "{!r}.".format(dn))
316
317 hostname_leftmost, sep, hostname_remainder = hostname.partition('.')
318 if not hostname_leftmost or not sep:
319 # wildcard must match at least one char
320 return False
321 return dn_remainder.lower() == hostname_remainder.lower()
322
323
324def _inet_paton(ipname):
325 """Try to convert an IP address to packed binary form
326
327 Supports IPv4 addresses on all platforms and IPv6 on platforms with IPv6
328 support.
329 """
Christian Heimes477b1b22019-07-02 20:39:42 +0200330 # inet_aton() also accepts strings like '1', '127.1', some also trailing
331 # data like '127.0.0.1 whatever'.
332 try:
333 addr = _socket.inet_aton(ipname)
334 except OSError:
335 # not an IPv4 address
336 pass
337 else:
338 if _socket.inet_ntoa(addr) == ipname:
339 # only accept injective ipnames
340 return addr
341 else:
342 # refuse for short IPv4 notation and additional trailing data
343 raise ValueError(
344 "{!r} is not a quad-dotted IPv4 address.".format(ipname)
345 )
Christian Heimesaef12832018-02-24 14:35:56 +0100346
347 try:
348 return _socket.inet_pton(_socket.AF_INET6, ipname)
349 except OSError:
350 raise ValueError("{!r} is neither an IPv4 nor an IP6 "
351 "address.".format(ipname))
352 except AttributeError:
353 # AF_INET6 not available
354 pass
355
356 raise ValueError("{!r} is not an IPv4 address.".format(ipname))
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000357
358
Christian Heimes477b1b22019-07-02 20:39:42 +0200359def _ipaddress_match(cert_ipaddress, host_ip):
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100360 """Exact matching of IP addresses.
361
362 RFC 6125 explicitly doesn't define an algorithm for this
363 (section 1.7.2 - "Out of Scope").
364 """
Christian Heimes477b1b22019-07-02 20:39:42 +0200365 # OpenSSL may add a trailing newline to a subjectAltName's IP address,
366 # commonly woth IPv6 addresses. Strip off trailing \n.
367 ip = _inet_paton(cert_ipaddress.rstrip())
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100368 return ip == host_ip
369
370
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000371def match_hostname(cert, hostname):
372 """Verify that *cert* (in decoded format as returned by
Georg Brandl72c98d32013-10-27 07:16:53 +0100373 SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
Christian Heimesaef12832018-02-24 14:35:56 +0100374 rules are followed.
375
376 The function matches IP addresses rather than dNSNames if hostname is a
377 valid ipaddress string. IPv4 addresses are supported on all platforms.
378 IPv6 addresses are supported on platforms with IPv6 support (AF_INET6
379 and inet_pton).
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000380
381 CertificateError is raised on failure. On success, the function
382 returns nothing.
383 """
Christian Heimes2875c602021-04-19 07:27:10 +0200384 warnings.warn(
385 "ssl module: match_hostname() is deprecated",
386 category=DeprecationWarning,
387 stacklevel=2
388 )
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000389 if not cert:
Christian Heimes1aa9a752013-12-02 02:41:19 +0100390 raise ValueError("empty or no certificate, match_hostname needs a "
391 "SSL socket or SSL context with either "
392 "CERT_OPTIONAL or CERT_REQUIRED")
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100393 try:
Christian Heimesaef12832018-02-24 14:35:56 +0100394 host_ip = _inet_paton(hostname)
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100395 except ValueError:
396 # Not an IP address (common case)
397 host_ip = None
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000398 dnsnames = []
399 san = cert.get('subjectAltName', ())
400 for key, value in san:
401 if key == 'DNS':
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100402 if host_ip is None and _dnsname_match(value, hostname):
403 return
404 dnsnames.append(value)
405 elif key == 'IP Address':
406 if host_ip is not None and _ipaddress_match(value, host_ip):
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000407 return
408 dnsnames.append(value)
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200409 if not dnsnames:
410 # The subject is only checked when there is no dNSName entry
411 # in subjectAltName
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000412 for sub in cert.get('subject', ()):
413 for key, value in sub:
414 # XXX according to RFC 2818, the most specific Common Name
415 # must be used.
416 if key == 'commonName':
Georg Brandl72c98d32013-10-27 07:16:53 +0100417 if _dnsname_match(value, hostname):
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000418 return
419 dnsnames.append(value)
420 if len(dnsnames) > 1:
421 raise CertificateError("hostname %r "
422 "doesn't match either of %s"
423 % (hostname, ', '.join(map(repr, dnsnames))))
424 elif len(dnsnames) == 1:
425 raise CertificateError("hostname %r "
426 "doesn't match %r"
427 % (hostname, dnsnames[0]))
428 else:
429 raise CertificateError("no appropriate commonName or "
430 "subjectAltName fields were found")
431
432
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100433DefaultVerifyPaths = namedtuple("DefaultVerifyPaths",
Christian Heimes6d7ad132013-06-09 18:02:55 +0200434 "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env "
435 "openssl_capath")
436
437def get_default_verify_paths():
438 """Return paths to default cafile and capath.
439 """
440 parts = _ssl.get_default_verify_paths()
441
442 # environment vars shadow paths
443 cafile = os.environ.get(parts[0], parts[1])
444 capath = os.environ.get(parts[2], parts[3])
445
446 return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None,
447 capath if os.path.isdir(capath) else None,
448 *parts)
449
450
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100451class _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")):
452 """ASN.1 object identifier lookup
453 """
454 __slots__ = ()
455
456 def __new__(cls, oid):
457 return super().__new__(cls, *_txt2obj(oid, name=False))
458
459 @classmethod
460 def fromnid(cls, nid):
461 """Create _ASN1Object from OpenSSL numeric ID
462 """
463 return super().__new__(cls, *_nid2obj(nid))
464
465 @classmethod
466 def fromname(cls, name):
467 """Create _ASN1Object from short name, long name or OID
468 """
469 return super().__new__(cls, *_txt2obj(name, name=True))
470
471
Christian Heimes72d28502013-11-23 13:56:58 +0100472class Purpose(_ASN1Object, _Enum):
473 """SSLContext purpose flags with X509v3 Extended Key Usage objects
474 """
475 SERVER_AUTH = '1.3.6.1.5.5.7.3.1'
476 CLIENT_AUTH = '1.3.6.1.5.5.7.3.2'
477
478
Antoine Pitrou152efa22010-05-16 18:19:27 +0000479class SSLContext(_SSLContext):
480 """An SSLContext holds various SSL-related configuration options and
481 data, such as certificates and possibly a private key."""
Christian Heimes72d28502013-11-23 13:56:58 +0100482 _windows_cert_stores = ("CA", "ROOT")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000483
Christian Heimes4df60f12017-09-15 20:26:05 +0200484 sslsocket_class = None # SSLSocket is assigned later.
485 sslobject_class = None # SSLObject is assigned later.
486
Christian Heimes2875c602021-04-19 07:27:10 +0200487 def __new__(cls, protocol=None, *args, **kwargs):
488 if protocol is None:
489 warnings.warn(
490 "ssl module: "
491 "SSLContext() without protocol argument is deprecated.",
492 category=DeprecationWarning,
493 stacklevel=2
494 )
495 protocol = PROTOCOL_TLS
Antoine Pitrou8f85f902012-01-03 22:46:48 +0100496 self = _SSLContext.__new__(cls, protocol)
Antoine Pitrou8f85f902012-01-03 22:46:48 +0100497 return self
Antoine Pitrou152efa22010-05-16 18:19:27 +0000498
Christian Heimes11a14932018-02-24 02:35:08 +0100499 def _encode_hostname(self, hostname):
500 if hostname is None:
501 return None
502 elif isinstance(hostname, str):
503 return hostname.encode('idna').decode('ascii')
504 else:
505 return hostname.decode('ascii')
Antoine Pitrou152efa22010-05-16 18:19:27 +0000506
507 def wrap_socket(self, sock, server_side=False,
508 do_handshake_on_connect=True,
Antoine Pitroud5323212010-10-22 18:19:07 +0000509 suppress_ragged_eofs=True,
Christian Heimes99a65702016-09-10 23:44:53 +0200510 server_hostname=None, session=None):
Christian Heimes11a14932018-02-24 02:35:08 +0100511 # SSLSocket class handles server_hostname encoding before it calls
512 # ctx._wrap_socket()
Christian Heimes9d50ab52018-02-27 10:17:30 +0100513 return self.sslsocket_class._create(
Christian Heimes4df60f12017-09-15 20:26:05 +0200514 sock=sock,
515 server_side=server_side,
516 do_handshake_on_connect=do_handshake_on_connect,
517 suppress_ragged_eofs=suppress_ragged_eofs,
518 server_hostname=server_hostname,
Christian Heimes9d50ab52018-02-27 10:17:30 +0100519 context=self,
520 session=session
Christian Heimes4df60f12017-09-15 20:26:05 +0200521 )
Antoine Pitrou152efa22010-05-16 18:19:27 +0000522
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200523 def wrap_bio(self, incoming, outgoing, server_side=False,
Christian Heimes99a65702016-09-10 23:44:53 +0200524 server_hostname=None, session=None):
Christian Heimes11a14932018-02-24 02:35:08 +0100525 # Need to encode server_hostname here because _wrap_bio() can only
526 # handle ASCII str.
Christian Heimes9d50ab52018-02-27 10:17:30 +0100527 return self.sslobject_class._create(
Christian Heimes11a14932018-02-24 02:35:08 +0100528 incoming, outgoing, server_side=server_side,
Christian Heimes141c5e82018-02-24 21:10:57 +0100529 server_hostname=self._encode_hostname(server_hostname),
Christian Heimes9d50ab52018-02-27 10:17:30 +0100530 session=session, context=self,
Christian Heimes11a14932018-02-24 02:35:08 +0100531 )
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200532
Antoine Pitroud5d17eb2012-03-22 00:23:03 +0100533 def set_npn_protocols(self, npn_protocols):
Christian Heimes2875c602021-04-19 07:27:10 +0200534 warnings.warn("NPN is deprecated, use ALPN instead", stacklevel=2)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +0100535 protos = bytearray()
536 for protocol in npn_protocols:
537 b = bytes(protocol, 'ascii')
538 if len(b) == 0 or len(b) > 255:
539 raise SSLError('NPN protocols must be 1 to 255 in length')
540 protos.append(len(b))
541 protos.extend(b)
542
543 self._set_npn_protocols(protos)
544
Christian Heimes11a14932018-02-24 02:35:08 +0100545 def set_servername_callback(self, server_name_callback):
546 if server_name_callback is None:
547 self.sni_callback = None
548 else:
549 if not callable(server_name_callback):
550 raise TypeError("not a callable object")
551
552 def shim_cb(sslobj, servername, sslctx):
553 servername = self._encode_hostname(servername)
554 return server_name_callback(sslobj, servername, sslctx)
555
556 self.sni_callback = shim_cb
557
Benjamin Petersoncca27322015-01-23 16:35:37 -0500558 def set_alpn_protocols(self, alpn_protocols):
559 protos = bytearray()
560 for protocol in alpn_protocols:
561 b = bytes(protocol, 'ascii')
562 if len(b) == 0 or len(b) > 255:
563 raise SSLError('ALPN protocols must be 1 to 255 in length')
564 protos.append(len(b))
565 protos.extend(b)
566
567 self._set_alpn_protocols(protos)
568
Christian Heimes72d28502013-11-23 13:56:58 +0100569 def _load_windows_store_certs(self, storename, purpose):
570 certs = bytearray()
Steve Dower33bc4a22016-05-26 12:18:12 -0700571 try:
572 for cert, encoding, trust in enum_certificates(storename):
573 # CA certs are never PKCS#7 encoded
574 if encoding == "x509_asn":
575 if trust is True or purpose.oid in trust:
576 certs.extend(cert)
577 except PermissionError:
578 warnings.warn("unable to enumerate Windows certificate store")
Steve Dower8dd7aeb2016-03-17 15:02:39 -0700579 if certs:
580 self.load_verify_locations(cadata=certs)
Christian Heimes72d28502013-11-23 13:56:58 +0100581 return certs
582
583 def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
584 if not isinstance(purpose, _ASN1Object):
585 raise TypeError(purpose)
586 if sys.platform == "win32":
587 for storename in self._windows_cert_stores:
588 self._load_windows_store_certs(storename, purpose)
Benjamin Peterson5915b0f2014-10-03 17:27:05 -0400589 self.set_default_verify_paths()
Christian Heimes72d28502013-11-23 13:56:58 +0100590
Christian Heimes698dde12018-02-27 11:54:43 +0100591 if hasattr(_SSLContext, 'minimum_version'):
592 @property
593 def minimum_version(self):
594 return TLSVersion(super().minimum_version)
595
596 @minimum_version.setter
597 def minimum_version(self, value):
598 if value == TLSVersion.SSLv3:
599 self.options &= ~Options.OP_NO_SSLv3
600 super(SSLContext, SSLContext).minimum_version.__set__(self, value)
601
602 @property
603 def maximum_version(self):
604 return TLSVersion(super().maximum_version)
605
606 @maximum_version.setter
607 def maximum_version(self, value):
608 super(SSLContext, SSLContext).maximum_version.__set__(self, value)
609
Christian Heimes3aeacad2016-09-10 00:19:35 +0200610 @property
611 def options(self):
612 return Options(super().options)
613
614 @options.setter
615 def options(self, value):
616 super(SSLContext, SSLContext).options.__set__(self, value)
617
Christian Heimes61d478c2018-01-27 15:51:38 +0100618 if hasattr(_ssl, 'HOSTFLAG_NEVER_CHECK_SUBJECT'):
619 @property
620 def hostname_checks_common_name(self):
621 ncs = self._host_flags & _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
622 return ncs != _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
623
624 @hostname_checks_common_name.setter
625 def hostname_checks_common_name(self, value):
626 if value:
627 self._host_flags &= ~_ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
628 else:
629 self._host_flags |= _ssl.HOSTFLAG_NEVER_CHECK_SUBJECT
630 else:
631 @property
632 def hostname_checks_common_name(self):
633 return True
634
Christian Heimes3aeacad2016-09-10 00:19:35 +0200635 @property
Christian Heimesc7f70692019-05-31 11:44:05 +0200636 def _msg_callback(self):
637 """TLS message callback
638
639 The message callback provides a debugging hook to analyze TLS
640 connections. The callback is called for any TLS protocol message
641 (header, handshake, alert, and more), but not for application data.
642 Due to technical limitations, the callback can't be used to filter
643 traffic or to abort a connection. Any exception raised in the
644 callback is delayed until the handshake, read, or write operation
645 has been performed.
646
647 def msg_cb(conn, direction, version, content_type, msg_type, data):
648 pass
649
650 conn
651 :class:`SSLSocket` or :class:`SSLObject` instance
652 direction
653 ``read`` or ``write``
654 version
655 :class:`TLSVersion` enum member or int for unknown version. For a
656 frame header, it's the header version.
657 content_type
658 :class:`_TLSContentType` enum member or int for unsupported
659 content type.
660 msg_type
661 Either a :class:`_TLSContentType` enum number for a header
662 message, a :class:`_TLSAlertType` enum member for an alert
663 message, a :class:`_TLSMessageType` enum member for other
664 messages, or int for unsupported message types.
665 data
666 Raw, decrypted message content as bytes
667 """
668 inner = super()._msg_callback
669 if inner is not None:
670 return inner.user_function
671 else:
672 return None
673
674 @_msg_callback.setter
675 def _msg_callback(self, callback):
676 if callback is None:
677 super(SSLContext, SSLContext)._msg_callback.__set__(self, None)
678 return
679
680 if not hasattr(callback, '__call__'):
681 raise TypeError(f"{callback} is not callable.")
682
683 def inner(conn, direction, version, content_type, msg_type, data):
684 try:
685 version = TLSVersion(version)
Christian Heimese35d1ba2019-06-03 20:40:15 +0200686 except ValueError:
Christian Heimesc7f70692019-05-31 11:44:05 +0200687 pass
688
689 try:
690 content_type = _TLSContentType(content_type)
Christian Heimese35d1ba2019-06-03 20:40:15 +0200691 except ValueError:
Christian Heimesc7f70692019-05-31 11:44:05 +0200692 pass
693
694 if content_type == _TLSContentType.HEADER:
695 msg_enum = _TLSContentType
696 elif content_type == _TLSContentType.ALERT:
697 msg_enum = _TLSAlertType
698 else:
699 msg_enum = _TLSMessageType
700 try:
701 msg_type = msg_enum(msg_type)
Christian Heimese35d1ba2019-06-03 20:40:15 +0200702 except ValueError:
Christian Heimesc7f70692019-05-31 11:44:05 +0200703 pass
704
705 return callback(conn, direction, version,
706 content_type, msg_type, data)
707
708 inner.user_function = callback
709
710 super(SSLContext, SSLContext)._msg_callback.__set__(self, inner)
711
712 @property
Christian Heimes11a14932018-02-24 02:35:08 +0100713 def protocol(self):
714 return _SSLMethod(super().protocol)
715
716 @property
Christian Heimes3aeacad2016-09-10 00:19:35 +0200717 def verify_flags(self):
718 return VerifyFlags(super().verify_flags)
719
720 @verify_flags.setter
721 def verify_flags(self, value):
722 super(SSLContext, SSLContext).verify_flags.__set__(self, value)
723
724 @property
725 def verify_mode(self):
726 value = super().verify_mode
727 try:
728 return VerifyMode(value)
729 except ValueError:
730 return value
731
732 @verify_mode.setter
733 def verify_mode(self, value):
734 super(SSLContext, SSLContext).verify_mode.__set__(self, value)
735
Antoine Pitrou152efa22010-05-16 18:19:27 +0000736
Christian Heimes4c05b472013-11-23 15:58:30 +0100737def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
738 capath=None, cadata=None):
739 """Create a SSLContext object with default settings.
740
741 NOTE: The protocol and settings may change anytime without prior
742 deprecation. The values represent a fair balance between maximum
743 compatibility and security.
744 """
745 if not isinstance(purpose, _ASN1Object):
746 raise TypeError(purpose)
Donald Stufft6a2ba942014-03-23 19:05:28 -0400747
Christian Heimes358cfd42016-09-10 22:43:48 +0200748 # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
749 # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
750 # by default.
Christian Heimes4c05b472013-11-23 15:58:30 +0100751 if purpose == Purpose.SERVER_AUTH:
Donald Stufft6a2ba942014-03-23 19:05:28 -0400752 # verify certs and host name in client mode
Christian Heimes2875c602021-04-19 07:27:10 +0200753 context = SSLContext(PROTOCOL_TLS_CLIENT)
Christian Heimes4c05b472013-11-23 15:58:30 +0100754 context.verify_mode = CERT_REQUIRED
Christian Heimes1aa9a752013-12-02 02:41:19 +0100755 context.check_hostname = True
Christian Heimes2875c602021-04-19 07:27:10 +0200756 elif purpose == Purpose.CLIENT_AUTH:
757 context = SSLContext(PROTOCOL_TLS_SERVER)
758 else:
759 raise ValueError(purpose)
Donald Stufft6a2ba942014-03-23 19:05:28 -0400760
Christian Heimes4c05b472013-11-23 15:58:30 +0100761 if cafile or capath or cadata:
762 context.load_verify_locations(cafile, capath, cadata)
763 elif context.verify_mode != CERT_NONE:
764 # no explicit cafile, capath or cadata but the verify mode is
765 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
766 # root CA certificates for the given purpose. This may fail silently.
767 context.load_default_certs(purpose)
Christian Heimesc7f70692019-05-31 11:44:05 +0200768 # OpenSSL 1.1.1 keylog file
769 if hasattr(context, 'keylog_filename'):
770 keylogfile = os.environ.get('SSLKEYLOGFILE')
771 if keylogfile and not sys.flags.ignore_environment:
772 context.keylog_filename = keylogfile
Christian Heimes4c05b472013-11-23 15:58:30 +0100773 return context
774
Christian Heimes2875c602021-04-19 07:27:10 +0200775def _create_unverified_context(protocol=None, *, cert_reqs=CERT_NONE,
Christian Heimesa02c69a2013-12-02 20:59:28 +0100776 check_hostname=False, purpose=Purpose.SERVER_AUTH,
Christian Heimes67986f92013-11-23 22:43:47 +0100777 certfile=None, keyfile=None,
778 cafile=None, capath=None, cadata=None):
779 """Create a SSLContext object for Python stdlib modules
780
781 All Python stdlib modules shall use this function to create SSLContext
782 objects in order to keep common settings in one place. The configuration
783 is less restrict than create_default_context()'s to increase backward
784 compatibility.
785 """
786 if not isinstance(purpose, _ASN1Object):
787 raise TypeError(purpose)
788
Christian Heimes358cfd42016-09-10 22:43:48 +0200789 # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
790 # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
791 # by default.
Christian Heimes2875c602021-04-19 07:27:10 +0200792 if purpose == Purpose.SERVER_AUTH:
793 # verify certs and host name in client mode
794 if protocol is None:
795 protocol = PROTOCOL_TLS_CLIENT
796 elif purpose == Purpose.CLIENT_AUTH:
797 if protocol is None:
798 protocol = PROTOCOL_TLS_SERVER
799 else:
800 raise ValueError(purpose)
Christian Heimes67986f92013-11-23 22:43:47 +0100801
Christian Heimes2875c602021-04-19 07:27:10 +0200802 context = SSLContext(protocol)
803 context.check_hostname = check_hostname
Christian Heimes67986f92013-11-23 22:43:47 +0100804 if cert_reqs is not None:
805 context.verify_mode = cert_reqs
Christian Heimesa170fa12017-09-15 20:27:30 +0200806 if check_hostname:
807 context.check_hostname = True
Christian Heimes67986f92013-11-23 22:43:47 +0100808
809 if keyfile and not certfile:
810 raise ValueError("certfile must be specified")
811 if certfile or keyfile:
812 context.load_cert_chain(certfile, keyfile)
813
814 # load CA root certs
815 if cafile or capath or cadata:
816 context.load_verify_locations(cafile, capath, cadata)
817 elif context.verify_mode != CERT_NONE:
818 # no explicit cafile, capath or cadata but the verify mode is
819 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
820 # root CA certificates for the given purpose. This may fail silently.
821 context.load_default_certs(purpose)
Christian Heimesc7f70692019-05-31 11:44:05 +0200822 # OpenSSL 1.1.1 keylog file
823 if hasattr(context, 'keylog_filename'):
824 keylogfile = os.environ.get('SSLKEYLOGFILE')
825 if keylogfile and not sys.flags.ignore_environment:
826 context.keylog_filename = keylogfile
Christian Heimes67986f92013-11-23 22:43:47 +0100827 return context
828
Benjamin Peterson4ffb0752014-11-03 14:29:33 -0500829# Used by http.client if no context is explicitly passed.
830_create_default_https_context = create_default_context
831
832
833# Backwards compatibility alias, even though it's not a public name.
834_create_stdlib_context = _create_unverified_context
835
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200836
837class SSLObject:
838 """This class implements an interface on top of a low-level SSL object as
839 implemented by OpenSSL. This object captures the state of an SSL connection
840 but does not provide any network IO itself. IO needs to be performed
841 through separate "BIO" objects which are OpenSSL's IO abstraction layer.
842
843 This class does not have a public constructor. Instances are returned by
844 ``SSLContext.wrap_bio``. This class is typically used by framework authors
845 that want to implement asynchronous IO for SSL through memory buffers.
846
847 When compared to ``SSLSocket``, this object lacks the following features:
848
Matt Eatonfc7d1b32018-10-05 02:00:45 -0500849 * Any form of network IO, including methods such as ``recv`` and ``send``.
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200850 * The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery.
851 """
Christian Heimes9d50ab52018-02-27 10:17:30 +0100852 def __init__(self, *args, **kwargs):
853 raise TypeError(
854 f"{self.__class__.__name__} does not have a public "
855 f"constructor. Instances are returned by SSLContext.wrap_bio()."
856 )
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200857
Christian Heimes9d50ab52018-02-27 10:17:30 +0100858 @classmethod
859 def _create(cls, incoming, outgoing, server_side=False,
860 server_hostname=None, session=None, context=None):
861 self = cls.__new__(cls)
862 sslobj = context._wrap_bio(
Christian Heimes141c5e82018-02-24 21:10:57 +0100863 incoming, outgoing, server_side=server_side,
864 server_hostname=server_hostname,
865 owner=self, session=session
866 )
Christian Heimes9d50ab52018-02-27 10:17:30 +0100867 self._sslobj = sslobj
868 return self
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200869
870 @property
871 def context(self):
872 """The SSLContext that is currently in use."""
873 return self._sslobj.context
874
875 @context.setter
876 def context(self, ctx):
877 self._sslobj.context = ctx
878
879 @property
Christian Heimes99a65702016-09-10 23:44:53 +0200880 def session(self):
881 """The SSLSession for client socket."""
882 return self._sslobj.session
883
884 @session.setter
885 def session(self, session):
886 self._sslobj.session = session
887
888 @property
889 def session_reused(self):
890 """Was the client session reused during handshake"""
891 return self._sslobj.session_reused
892
893 @property
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200894 def server_side(self):
895 """Whether this is a server-side socket."""
896 return self._sslobj.server_side
897
898 @property
899 def server_hostname(self):
900 """The currently set server hostname (for SNI), or ``None`` if no
Xtreak0d702272019-06-03 04:42:33 +0530901 server hostname is set."""
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200902 return self._sslobj.server_hostname
903
Martin Panterf6b1d662016-03-28 00:22:09 +0000904 def read(self, len=1024, buffer=None):
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200905 """Read up to 'len' bytes from the SSL object and return them.
906
907 If 'buffer' is provided, read into this buffer and return the number of
908 bytes read.
909 """
910 if buffer is not None:
911 v = self._sslobj.read(len, buffer)
912 else:
Martin Panterf6b1d662016-03-28 00:22:09 +0000913 v = self._sslobj.read(len)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200914 return v
915
916 def write(self, data):
917 """Write 'data' to the SSL object and return the number of bytes
918 written.
919
920 The 'data' argument must support the buffer interface.
921 """
922 return self._sslobj.write(data)
923
924 def getpeercert(self, binary_form=False):
925 """Returns a formatted version of the data in the certificate provided
926 by the other end of the SSL channel.
927
928 Return None if no certificate was provided, {} if a certificate was
929 provided, but not validated.
930 """
Christian Heimes141c5e82018-02-24 21:10:57 +0100931 return self._sslobj.getpeercert(binary_form)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200932
933 def selected_npn_protocol(self):
934 """Return the currently selected NPN protocol as a string, or ``None``
935 if a next protocol was not negotiated or if NPN is not supported by one
936 of the peers."""
Christian Heimes2875c602021-04-19 07:27:10 +0200937 warnings.warn(
938 "ssl module: NPN is deprecated, use ALPN instead", stacklevel=2
939 )
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200940
Benjamin Petersoncca27322015-01-23 16:35:37 -0500941 def selected_alpn_protocol(self):
942 """Return the currently selected ALPN protocol as a string, or ``None``
943 if a next protocol was not negotiated or if ALPN is not supported by one
944 of the peers."""
Christian Heimes39258d32021-04-17 11:36:35 +0200945 return self._sslobj.selected_alpn_protocol()
Benjamin Petersoncca27322015-01-23 16:35:37 -0500946
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200947 def cipher(self):
948 """Return the currently selected cipher as a 3-tuple ``(name,
949 ssl_version, secret_bits)``."""
950 return self._sslobj.cipher()
951
Benjamin Peterson4cb17812015-01-07 11:14:26 -0600952 def shared_ciphers(self):
Benjamin Petersonc114e7d2015-01-11 15:22:07 -0500953 """Return a list of ciphers shared by the client during the handshake or
954 None if this is not a valid server connection.
Benjamin Peterson5318c7a2015-01-07 11:26:50 -0600955 """
Benjamin Peterson4cb17812015-01-07 11:14:26 -0600956 return self._sslobj.shared_ciphers()
957
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200958 def compression(self):
959 """Return the current compression algorithm in use, or ``None`` if
960 compression was not negotiated or not supported by one of the peers."""
961 return self._sslobj.compression()
962
963 def pending(self):
964 """Return the number of bytes that can be read immediately."""
965 return self._sslobj.pending()
966
Antoine Pitrou3cb93792014-10-06 00:21:09 +0200967 def do_handshake(self):
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200968 """Start the SSL/TLS handshake."""
969 self._sslobj.do_handshake()
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200970
971 def unwrap(self):
972 """Start the SSL shutdown handshake."""
973 return self._sslobj.shutdown()
974
975 def get_channel_binding(self, cb_type="tls-unique"):
976 """Get channel binding data for current connection. Raise ValueError
977 if the requested `cb_type` is not supported. Return bytes of the data
978 or None if the data is not available (e.g. before the handshake)."""
Christian Heimes141c5e82018-02-24 21:10:57 +0100979 return self._sslobj.get_channel_binding(cb_type)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200980
981 def version(self):
982 """Return a string identifying the protocol version used by the
983 current SSL channel. """
984 return self._sslobj.version()
985
Christian Heimes9fb051f2018-09-23 08:32:31 +0200986 def verify_client_post_handshake(self):
987 return self._sslobj.verify_client_post_handshake()
988
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200989
Christian Heimes80ed3532019-05-17 13:08:14 +0200990def _sslcopydoc(func):
991 """Copy docstring from SSLObject to SSLSocket"""
992 func.__doc__ = getattr(SSLObject, func.__name__).__doc__
993 return func
994
995
Antoine Pitrou152efa22010-05-16 18:19:27 +0000996class SSLSocket(socket):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000997 """This class implements a subtype of socket.socket that wraps
998 the underlying OS socket in an SSL context when necessary, and
Christian Heimes9d50ab52018-02-27 10:17:30 +0100999 provides read and write methods over that channel. """
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001000
Christian Heimes9d50ab52018-02-27 10:17:30 +01001001 def __init__(self, *args, **kwargs):
1002 raise TypeError(
1003 f"{self.__class__.__name__} does not have a public "
1004 f"constructor. Instances are returned by "
1005 f"SSLContext.wrap_socket()."
1006 )
Bill Janssen6e027db2007-11-15 22:23:56 +00001007
Christian Heimes9d50ab52018-02-27 10:17:30 +01001008 @classmethod
1009 def _create(cls, sock, server_side=False, do_handshake_on_connect=True,
1010 suppress_ragged_eofs=True, server_hostname=None,
1011 context=None, session=None):
Antoine Pitrou3e86ba42013-12-28 17:26:33 +01001012 if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
1013 raise NotImplementedError("only stream sockets are supported")
Christian Heimes99a65702016-09-10 23:44:53 +02001014 if server_side:
1015 if server_hostname:
1016 raise ValueError("server_hostname can only be specified "
1017 "in client mode")
Christian Heimes9d50ab52018-02-27 10:17:30 +01001018 if session is not None:
Christian Heimes99a65702016-09-10 23:44:53 +02001019 raise ValueError("session can only be specified in "
1020 "client mode")
Christian Heimes9d50ab52018-02-27 10:17:30 +01001021 if context.check_hostname and not server_hostname:
Benjamin Peterson7243b572014-11-23 17:04:34 -06001022 raise ValueError("check_hostname requires server_hostname")
Christian Heimes9d50ab52018-02-27 10:17:30 +01001023
1024 kwargs = dict(
1025 family=sock.family, type=sock.type, proto=sock.proto,
1026 fileno=sock.fileno()
1027 )
1028 self = cls.__new__(cls, **kwargs)
1029 super(SSLSocket, self).__init__(**kwargs)
1030 self.settimeout(sock.gettimeout())
1031 sock.detach()
1032
1033 self._context = context
1034 self._session = session
1035 self._closed = False
1036 self._sslobj = None
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001037 self.server_side = server_side
Christian Heimes9d50ab52018-02-27 10:17:30 +01001038 self.server_hostname = context._encode_hostname(server_hostname)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001039 self.do_handshake_on_connect = do_handshake_on_connect
1040 self.suppress_ragged_eofs = suppress_ragged_eofs
Bill Janssen6e027db2007-11-15 22:23:56 +00001041
Antoine Pitrou242db722013-05-01 20:52:07 +02001042 # See if we are connected
1043 try:
1044 self.getpeername()
1045 except OSError as e:
1046 if e.errno != errno.ENOTCONN:
1047 raise
1048 connected = False
1049 else:
1050 connected = True
1051
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001052 self._connected = connected
Antoine Pitroufa2b9382010-04-26 22:17:47 +00001053 if connected:
1054 # create the SSL object
Bill Janssen6e027db2007-11-15 22:23:56 +00001055 try:
Christian Heimes141c5e82018-02-24 21:10:57 +01001056 self._sslobj = self._context._wrap_socket(
1057 self, server_side, self.server_hostname,
1058 owner=self, session=self._session,
1059 )
Bill Janssen6e027db2007-11-15 22:23:56 +00001060 if do_handshake_on_connect:
Bill Janssen48dc27c2007-12-05 03:38:10 +00001061 timeout = self.gettimeout()
1062 if timeout == 0.0:
1063 # non-blocking
1064 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
Bill Janssen6e027db2007-11-15 22:23:56 +00001065 self.do_handshake()
Christian Heimes1aa9a752013-12-02 02:41:19 +01001066 except (OSError, ValueError):
Bill Janssen6e027db2007-11-15 22:23:56 +00001067 self.close()
Christian Heimes1aa9a752013-12-02 02:41:19 +01001068 raise
Christian Heimes9d50ab52018-02-27 10:17:30 +01001069 return self
Antoine Pitrou242db722013-05-01 20:52:07 +02001070
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001071 @property
Christian Heimes80ed3532019-05-17 13:08:14 +02001072 @_sslcopydoc
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001073 def context(self):
1074 return self._context
1075
1076 @context.setter
1077 def context(self, ctx):
1078 self._context = ctx
1079 self._sslobj.context = ctx
Bill Janssen6e027db2007-11-15 22:23:56 +00001080
Christian Heimes99a65702016-09-10 23:44:53 +02001081 @property
Christian Heimes80ed3532019-05-17 13:08:14 +02001082 @_sslcopydoc
Christian Heimes99a65702016-09-10 23:44:53 +02001083 def session(self):
Christian Heimes99a65702016-09-10 23:44:53 +02001084 if self._sslobj is not None:
1085 return self._sslobj.session
1086
1087 @session.setter
1088 def session(self, session):
1089 self._session = session
1090 if self._sslobj is not None:
1091 self._sslobj.session = session
1092
1093 @property
Christian Heimes80ed3532019-05-17 13:08:14 +02001094 @_sslcopydoc
Christian Heimes99a65702016-09-10 23:44:53 +02001095 def session_reused(self):
Christian Heimes99a65702016-09-10 23:44:53 +02001096 if self._sslobj is not None:
1097 return self._sslobj.session_reused
1098
Guido van Rossumb7b030e2007-11-16 01:28:45 +00001099 def dup(self):
Serhiy Storchaka42b1d612018-12-06 22:36:55 +02001100 raise NotImplementedError("Can't dup() %s instances" %
1101 self.__class__.__name__)
Guido van Rossumb7b030e2007-11-16 01:28:45 +00001102
Bill Janssen6e027db2007-11-15 22:23:56 +00001103 def _checkClosed(self, msg=None):
1104 # raise an exception here if you wish to check for spurious closes
1105 pass
1106
Antoine Pitrou242db722013-05-01 20:52:07 +02001107 def _check_connected(self):
1108 if not self._connected:
1109 # getpeername() will raise ENOTCONN if the socket is really
1110 # not connected; note that we can be connected even without
1111 # _connected being set, e.g. if connect() first returned
1112 # EAGAIN.
1113 self.getpeername()
1114
Martin Panterf6b1d662016-03-28 00:22:09 +00001115 def read(self, len=1024, buffer=None):
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001116 """Read up to LEN bytes and return them.
1117 Return zero-length string on EOF."""
1118
Bill Janssen6e027db2007-11-15 22:23:56 +00001119 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001120 if self._sslobj is None:
Antoine Pitrou60a26e02013-07-20 19:35:16 +02001121 raise ValueError("Read on closed or unwrapped SSL socket.")
Bill Janssen6e027db2007-11-15 22:23:56 +00001122 try:
Christian Heimes141c5e82018-02-24 21:10:57 +01001123 if buffer is not None:
1124 return self._sslobj.read(len, buffer)
1125 else:
1126 return self._sslobj.read(len)
Bill Janssen6e027db2007-11-15 22:23:56 +00001127 except SSLError as x:
1128 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
Antoine Pitrou24e561a2010-09-03 18:38:17 +00001129 if buffer is not None:
Bill Janssen54cc54c2007-12-14 22:08:56 +00001130 return 0
1131 else:
1132 return b''
Bill Janssen6e027db2007-11-15 22:23:56 +00001133 else:
1134 raise
Thomas Woutersed03b412007-08-28 21:37:11 +00001135
1136 def write(self, data):
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001137 """Write DATA to the underlying SSL channel. Returns
1138 number of bytes of DATA actually transmitted."""
1139
Bill Janssen6e027db2007-11-15 22:23:56 +00001140 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001141 if self._sslobj is None:
Antoine Pitrou60a26e02013-07-20 19:35:16 +02001142 raise ValueError("Write on closed or unwrapped SSL socket.")
Thomas Woutersed03b412007-08-28 21:37:11 +00001143 return self._sslobj.write(data)
1144
Christian Heimes80ed3532019-05-17 13:08:14 +02001145 @_sslcopydoc
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001146 def getpeercert(self, binary_form=False):
Bill Janssen6e027db2007-11-15 22:23:56 +00001147 self._checkClosed()
Antoine Pitrou242db722013-05-01 20:52:07 +02001148 self._check_connected()
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001149 return self._sslobj.getpeercert(binary_form)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001150
Christian Heimes80ed3532019-05-17 13:08:14 +02001151 @_sslcopydoc
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001152 def selected_npn_protocol(self):
1153 self._checkClosed()
Christian Heimes2875c602021-04-19 07:27:10 +02001154 warnings.warn(
1155 "ssl module: NPN is deprecated, use ALPN instead", stacklevel=2
1156 )
Christian Heimes39258d32021-04-17 11:36:35 +02001157 return None
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001158
Christian Heimes80ed3532019-05-17 13:08:14 +02001159 @_sslcopydoc
Benjamin Petersoncca27322015-01-23 16:35:37 -05001160 def selected_alpn_protocol(self):
1161 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001162 if self._sslobj is None or not _ssl.HAS_ALPN:
Benjamin Petersoncca27322015-01-23 16:35:37 -05001163 return None
1164 else:
1165 return self._sslobj.selected_alpn_protocol()
1166
Christian Heimes80ed3532019-05-17 13:08:14 +02001167 @_sslcopydoc
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001168 def cipher(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001169 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001170 if self._sslobj is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001171 return None
1172 else:
1173 return self._sslobj.cipher()
Thomas Woutersed03b412007-08-28 21:37:11 +00001174
Christian Heimes80ed3532019-05-17 13:08:14 +02001175 @_sslcopydoc
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001176 def shared_ciphers(self):
1177 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001178 if self._sslobj is None:
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001179 return None
Christian Heimes141c5e82018-02-24 21:10:57 +01001180 else:
1181 return self._sslobj.shared_ciphers()
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001182
Christian Heimes80ed3532019-05-17 13:08:14 +02001183 @_sslcopydoc
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01001184 def compression(self):
1185 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001186 if self._sslobj is None:
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01001187 return None
1188 else:
1189 return self._sslobj.compression()
1190
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001191 def send(self, data, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001192 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001193 if self._sslobj is not None:
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001194 if flags != 0:
1195 raise ValueError(
1196 "non-zero flags not allowed in calls to send() on %s" %
1197 self.__class__)
Antoine Pitroub4bebda2014-04-29 10:03:28 +02001198 return self._sslobj.write(data)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001199 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001200 return super().send(data, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001201
Antoine Pitroua468adc2010-09-14 14:43:44 +00001202 def sendto(self, data, flags_or_addr, addr=None):
Bill Janssen6e027db2007-11-15 22:23:56 +00001203 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001204 if self._sslobj is not None:
Bill Janssen980f3142008-06-29 00:05:51 +00001205 raise ValueError("sendto not allowed on instances of %s" %
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001206 self.__class__)
Antoine Pitroua468adc2010-09-14 14:43:44 +00001207 elif addr is None:
Mads Jensen746cc752018-01-27 13:34:28 +01001208 return super().sendto(data, flags_or_addr)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001209 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001210 return super().sendto(data, flags_or_addr, addr)
Thomas Woutersed03b412007-08-28 21:37:11 +00001211
Nick Coghlan513886a2011-08-28 00:00:27 +10001212 def sendmsg(self, *args, **kwargs):
1213 # Ensure programs don't send data unencrypted if they try to
1214 # use this method.
1215 raise NotImplementedError("sendmsg not allowed on instances of %s" %
1216 self.__class__)
1217
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001218 def sendall(self, data, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001219 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001220 if self._sslobj is not None:
Giampaolo Rodolà374f8352010-08-29 12:08:09 +00001221 if flags != 0:
1222 raise ValueError(
1223 "non-zero flags not allowed in calls to sendall() on %s" %
1224 self.__class__)
Bill Janssen6e027db2007-11-15 22:23:56 +00001225 count = 0
Christian Heimes888bbdc2017-09-07 14:18:21 -07001226 with memoryview(data) as view, view.cast("B") as byte_view:
1227 amount = len(byte_view)
1228 while count < amount:
1229 v = self.send(byte_view[count:])
1230 count += v
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001231 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001232 return super().sendall(data, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001233
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02001234 def sendfile(self, file, offset=0, count=None):
1235 """Send a file, possibly by using os.sendfile() if this is a
1236 clear-text socket. Return the total number of bytes sent.
1237 """
Christian Heimes141c5e82018-02-24 21:10:57 +01001238 if self._sslobj is not None:
1239 return self._sendfile_use_send(file, offset, count)
1240 else:
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02001241 # os.sendfile() works with plain sockets only
1242 return super().sendfile(file, offset, count)
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02001243
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001244 def recv(self, buflen=1024, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001245 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001246 if self._sslobj is not None:
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001247 if flags != 0:
1248 raise ValueError(
Antoine Pitrou5733c082010-03-22 14:49:10 +00001249 "non-zero flags not allowed in calls to recv() on %s" %
1250 self.__class__)
1251 return self.read(buflen)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001252 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001253 return super().recv(buflen, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001254
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001255 def recv_into(self, buffer, nbytes=None, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001256 self._checkClosed()
1257 if buffer and (nbytes is None):
1258 nbytes = len(buffer)
1259 elif nbytes is None:
1260 nbytes = 1024
Christian Heimes141c5e82018-02-24 21:10:57 +01001261 if self._sslobj is not None:
Bill Janssen6e027db2007-11-15 22:23:56 +00001262 if flags != 0:
1263 raise ValueError(
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001264 "non-zero flags not allowed in calls to recv_into() on %s" %
1265 self.__class__)
Antoine Pitrou5733c082010-03-22 14:49:10 +00001266 return self.read(nbytes, buffer)
Bill Janssen6e027db2007-11-15 22:23:56 +00001267 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001268 return super().recv_into(buffer, nbytes, flags)
Bill Janssen6e027db2007-11-15 22:23:56 +00001269
Antoine Pitroua468adc2010-09-14 14:43:44 +00001270 def recvfrom(self, buflen=1024, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +00001271 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001272 if self._sslobj is not None:
Bill Janssen980f3142008-06-29 00:05:51 +00001273 raise ValueError("recvfrom not allowed on instances of %s" %
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001274 self.__class__)
1275 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001276 return super().recvfrom(buflen, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +00001277
Bill Janssen58afe4c2008-09-08 16:45:19 +00001278 def recvfrom_into(self, buffer, nbytes=None, flags=0):
1279 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001280 if self._sslobj is not None:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001281 raise ValueError("recvfrom_into not allowed on instances of %s" %
1282 self.__class__)
1283 else:
Mads Jensen746cc752018-01-27 13:34:28 +01001284 return super().recvfrom_into(buffer, nbytes, flags)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001285
Nick Coghlan513886a2011-08-28 00:00:27 +10001286 def recvmsg(self, *args, **kwargs):
1287 raise NotImplementedError("recvmsg not allowed on instances of %s" %
1288 self.__class__)
1289
1290 def recvmsg_into(self, *args, **kwargs):
1291 raise NotImplementedError("recvmsg_into not allowed on instances of "
1292 "%s" % self.__class__)
1293
Christian Heimes80ed3532019-05-17 13:08:14 +02001294 @_sslcopydoc
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001295 def pending(self):
Bill Janssen6e027db2007-11-15 22:23:56 +00001296 self._checkClosed()
Christian Heimes141c5e82018-02-24 21:10:57 +01001297 if self._sslobj is not None:
Bill Janssen6e027db2007-11-15 22:23:56 +00001298 return self._sslobj.pending()
1299 else:
1300 return 0
1301
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001302 def shutdown(self, how):
Bill Janssen6e027db2007-11-15 22:23:56 +00001303 self._checkClosed()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001304 self._sslobj = None
Mads Jensen746cc752018-01-27 13:34:28 +01001305 super().shutdown(how)
Thomas Woutersed03b412007-08-28 21:37:11 +00001306
Christian Heimes80ed3532019-05-17 13:08:14 +02001307 @_sslcopydoc
Ezio Melottidc55e672010-01-18 09:15:14 +00001308 def unwrap(self):
Bill Janssen40a0f662008-08-12 16:56:25 +00001309 if self._sslobj:
Christian Heimes141c5e82018-02-24 21:10:57 +01001310 s = self._sslobj.shutdown()
Bill Janssen40a0f662008-08-12 16:56:25 +00001311 self._sslobj = None
1312 return s
1313 else:
1314 raise ValueError("No SSL wrapper around " + str(self))
1315
Christian Heimes80ed3532019-05-17 13:08:14 +02001316 @_sslcopydoc
Christian Heimes9fb051f2018-09-23 08:32:31 +02001317 def verify_client_post_handshake(self):
1318 if self._sslobj:
1319 return self._sslobj.verify_client_post_handshake()
1320 else:
1321 raise ValueError("No SSL wrapper around " + str(self))
1322
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001323 def _real_close(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001324 self._sslobj = None
Mads Jensen746cc752018-01-27 13:34:28 +01001325 super()._real_close()
Bill Janssen6e027db2007-11-15 22:23:56 +00001326
Christian Heimes80ed3532019-05-17 13:08:14 +02001327 @_sslcopydoc
Bill Janssen48dc27c2007-12-05 03:38:10 +00001328 def do_handshake(self, block=False):
Antoine Pitrou242db722013-05-01 20:52:07 +02001329 self._check_connected()
Bill Janssen48dc27c2007-12-05 03:38:10 +00001330 timeout = self.gettimeout()
Bill Janssen6e027db2007-11-15 22:23:56 +00001331 try:
Bill Janssen48dc27c2007-12-05 03:38:10 +00001332 if timeout == 0.0 and block:
1333 self.settimeout(None)
Bill Janssen6e027db2007-11-15 22:23:56 +00001334 self._sslobj.do_handshake()
Bill Janssen48dc27c2007-12-05 03:38:10 +00001335 finally:
1336 self.settimeout(timeout)
Thomas Woutersed03b412007-08-28 21:37:11 +00001337
Antoine Pitroub4410db2011-05-18 18:51:06 +02001338 def _real_connect(self, addr, connect_ex):
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001339 if self.server_side:
1340 raise ValueError("can't connect in server-side mode")
Thomas Woutersed03b412007-08-28 21:37:11 +00001341 # Here we assume that the socket is client-side, and not
1342 # connected at the time of the call. We connect it, then wrap it.
Christian Heimes141c5e82018-02-24 21:10:57 +01001343 if self._connected or self._sslobj is not None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001344 raise ValueError("attempt to connect already-connected SSLSocket!")
Christian Heimes141c5e82018-02-24 21:10:57 +01001345 self._sslobj = self.context._wrap_socket(
1346 self, False, self.server_hostname,
1347 owner=self, session=self._session
1348 )
Bill Janssen54cc54c2007-12-14 22:08:56 +00001349 try:
Antoine Pitroub4410db2011-05-18 18:51:06 +02001350 if connect_ex:
Mads Jensen746cc752018-01-27 13:34:28 +01001351 rc = super().connect_ex(addr)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001352 else:
Antoine Pitroub4410db2011-05-18 18:51:06 +02001353 rc = None
Mads Jensen746cc752018-01-27 13:34:28 +01001354 super().connect(addr)
Antoine Pitroub4410db2011-05-18 18:51:06 +02001355 if not rc:
Antoine Pitrou242db722013-05-01 20:52:07 +02001356 self._connected = True
Antoine Pitroub4410db2011-05-18 18:51:06 +02001357 if self.do_handshake_on_connect:
1358 self.do_handshake()
Antoine Pitroub4410db2011-05-18 18:51:06 +02001359 return rc
Christian Heimes1aa9a752013-12-02 02:41:19 +01001360 except (OSError, ValueError):
Antoine Pitroub4410db2011-05-18 18:51:06 +02001361 self._sslobj = None
1362 raise
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001363
1364 def connect(self, addr):
1365 """Connects to remote ADDR, and then wraps the connection in
1366 an SSL channel."""
1367 self._real_connect(addr, False)
1368
1369 def connect_ex(self, addr):
1370 """Connects to remote ADDR, and then wraps the connection in
1371 an SSL channel."""
1372 return self._real_connect(addr, True)
Thomas Woutersed03b412007-08-28 21:37:11 +00001373
1374 def accept(self):
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001375 """Accepts a new connection from a remote client, and returns
1376 a tuple containing that new connection wrapped with a server-side
1377 SSL channel, and the address of the remote client."""
1378
Mads Jensen746cc752018-01-27 13:34:28 +01001379 newsock, addr = super().accept()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01001380 newsock = self.context.wrap_socket(newsock,
1381 do_handshake_on_connect=self.do_handshake_on_connect,
1382 suppress_ragged_eofs=self.suppress_ragged_eofs,
1383 server_side=True)
1384 return newsock, addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001385
Christian Heimes80ed3532019-05-17 13:08:14 +02001386 @_sslcopydoc
Antoine Pitroud6494802011-07-21 01:11:30 +02001387 def get_channel_binding(self, cb_type="tls-unique"):
Christian Heimes141c5e82018-02-24 21:10:57 +01001388 if self._sslobj is not None:
1389 return self._sslobj.get_channel_binding(cb_type)
1390 else:
1391 if cb_type not in CHANNEL_BINDING_TYPES:
1392 raise ValueError(
1393 "{0} channel binding type not implemented".format(cb_type)
1394 )
Antoine Pitroud6494802011-07-21 01:11:30 +02001395 return None
Antoine Pitroud6494802011-07-21 01:11:30 +02001396
Christian Heimes80ed3532019-05-17 13:08:14 +02001397 @_sslcopydoc
Antoine Pitrou47e40422014-09-04 21:00:10 +02001398 def version(self):
Christian Heimes141c5e82018-02-24 21:10:57 +01001399 if self._sslobj is not None:
1400 return self._sslobj.version()
1401 else:
Antoine Pitrou47e40422014-09-04 21:00:10 +02001402 return None
Antoine Pitrou47e40422014-09-04 21:00:10 +02001403
Bill Janssen54cc54c2007-12-14 22:08:56 +00001404
Christian Heimes4df60f12017-09-15 20:26:05 +02001405# Python does not support forward declaration of types.
1406SSLContext.sslsocket_class = SSLSocket
1407SSLContext.sslobject_class = SSLObject
1408
1409
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001410def wrap_socket(sock, keyfile=None, certfile=None,
1411 server_side=False, cert_reqs=CERT_NONE,
Christian Heimes598894f2016-09-05 23:19:05 +02001412 ssl_version=PROTOCOL_TLS, ca_certs=None,
Bill Janssen48dc27c2007-12-05 03:38:10 +00001413 do_handshake_on_connect=True,
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001414 suppress_ragged_eofs=True,
1415 ciphers=None):
Christian Heimes2875c602021-04-19 07:27:10 +02001416 warnings.warn(
1417 "ssl module: wrap_socket is deprecated, use SSLContext.wrap_socket()",
1418 category=DeprecationWarning,
1419 stacklevel=2
1420 )
Christian Heimes9d50ab52018-02-27 10:17:30 +01001421 if server_side and not certfile:
1422 raise ValueError("certfile must be specified for server-side "
1423 "operations")
1424 if keyfile and not certfile:
1425 raise ValueError("certfile must be specified")
1426 context = SSLContext(ssl_version)
1427 context.verify_mode = cert_reqs
1428 if ca_certs:
1429 context.load_verify_locations(ca_certs)
1430 if certfile:
1431 context.load_cert_chain(certfile, keyfile)
1432 if ciphers:
1433 context.set_ciphers(ciphers)
1434 return context.wrap_socket(
1435 sock=sock, server_side=server_side,
1436 do_handshake_on_connect=do_handshake_on_connect,
1437 suppress_ragged_eofs=suppress_ragged_eofs
1438 )
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001439
Thomas Woutersed03b412007-08-28 21:37:11 +00001440# some utility functions
1441
1442def cert_time_to_seconds(cert_time):
Antoine Pitrouc695c952014-04-28 20:57:36 +02001443 """Return the time in seconds since the Epoch, given the timestring
1444 representing the "notBefore" or "notAfter" date from a certificate
1445 in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale).
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001446
Antoine Pitrouc695c952014-04-28 20:57:36 +02001447 "notBefore" or "notAfter" dates must use UTC (RFC 5280).
1448
1449 Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1450 UTC should be specified as GMT (see ASN1_TIME_print())
1451 """
1452 from time import strptime
1453 from calendar import timegm
1454
1455 months = (
1456 "Jan","Feb","Mar","Apr","May","Jun",
1457 "Jul","Aug","Sep","Oct","Nov","Dec"
1458 )
1459 time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT
1460 try:
1461 month_number = months.index(cert_time[:3].title()) + 1
1462 except ValueError:
1463 raise ValueError('time data %r does not match '
1464 'format "%%b%s"' % (cert_time, time_format))
1465 else:
1466 # found valid month
1467 tt = strptime(cert_time[3:], time_format)
1468 # return an integer, the previous mktime()-based implementation
1469 # returned a float (fractional seconds are always zero here).
1470 return timegm((tt[0], month_number) + tt[2:6])
Thomas Woutersed03b412007-08-28 21:37:11 +00001471
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001472PEM_HEADER = "-----BEGIN CERTIFICATE-----"
1473PEM_FOOTER = "-----END CERTIFICATE-----"
1474
1475def DER_cert_to_PEM_cert(der_cert_bytes):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001476 """Takes a certificate in binary DER format and returns the
1477 PEM version of it as a string."""
1478
Bill Janssen6e027db2007-11-15 22:23:56 +00001479 f = str(base64.standard_b64encode(der_cert_bytes), 'ASCII', 'strict')
INADA Naokib75a2282017-10-02 16:33:42 +09001480 ss = [PEM_HEADER]
1481 ss += [f[i:i+64] for i in range(0, len(f), 64)]
1482 ss.append(PEM_FOOTER + '\n')
1483 return '\n'.join(ss)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001484
1485def PEM_cert_to_DER_cert(pem_cert_string):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001486 """Takes a certificate in ASCII PEM format and returns the
1487 DER-encoded version of it as a byte sequence"""
1488
1489 if not pem_cert_string.startswith(PEM_HEADER):
1490 raise ValueError("Invalid PEM encoding; must start with %s"
1491 % PEM_HEADER)
1492 if not pem_cert_string.strip().endswith(PEM_FOOTER):
1493 raise ValueError("Invalid PEM encoding; must end with %s"
1494 % PEM_FOOTER)
1495 d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
Georg Brandl706824f2009-06-04 09:42:55 +00001496 return base64.decodebytes(d.encode('ASCII', 'strict'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001497
Christian Heimes2875c602021-04-19 07:27:10 +02001498def get_server_certificate(addr, ssl_version=PROTOCOL_TLS_CLIENT, ca_certs=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001499 """Retrieve the certificate from the server at the specified address,
1500 and return it as a PEM-encoded string.
1501 If 'ca_certs' is specified, validate the server cert against it.
1502 If 'ssl_version' is specified, use it in the connection attempt."""
1503
1504 host, port = addr
Christian Heimes67986f92013-11-23 22:43:47 +01001505 if ca_certs is not None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001506 cert_reqs = CERT_REQUIRED
1507 else:
1508 cert_reqs = CERT_NONE
Christian Heimes67986f92013-11-23 22:43:47 +01001509 context = _create_stdlib_context(ssl_version,
1510 cert_reqs=cert_reqs,
1511 cafile=ca_certs)
1512 with create_connection(addr) as sock:
juhovh49fdf112021-04-18 21:11:48 +10001513 with context.wrap_socket(sock, server_hostname=host) as sslsock:
Christian Heimes67986f92013-11-23 22:43:47 +01001514 dercert = sslsock.getpeercert(True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001515 return DER_cert_to_PEM_cert(dercert)
1516
Guido van Rossum5b8b1552007-11-16 00:06:11 +00001517def get_protocol_name(protocol_code):
Victor Stinner3de49192011-05-09 00:42:58 +02001518 return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')