blob: f28c863811fd9810988d107a9f24a3c8678aa284 [file] [log] [blame]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001# Wrapper module for _ssl, providing some additional facilities
2# implemented in Python. Written by Bill Janssen.
3
Benjamin Petersondaeb9252014-08-20 14:14:50 -05004"""This module provides some more Pythonic support for SSL.
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00005
6Object types:
7
Bill Janssen98d19da2007-09-10 21:51:02 +00008 SSLSocket -- subtype of socket.socket which does SSL over the socket
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00009
10Exceptions:
11
Bill Janssen98d19da2007-09-10 21:51:02 +000012 SSLError -- exception raised for I/O errors
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +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 Heimesc2fc7c42016-09-05 23:37:13 +020054PROTOCOL_TLS
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000055PROTOCOL_TLSv1
Benjamin Petersondaeb9252014-08-20 14:14:50 -050056PROTOCOL_TLSv1_1
57PROTOCOL_TLSv1_2
58
59The following constants identify various SSL alert message descriptions as per
60http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6
61
62ALERT_DESCRIPTION_CLOSE_NOTIFY
63ALERT_DESCRIPTION_UNEXPECTED_MESSAGE
64ALERT_DESCRIPTION_BAD_RECORD_MAC
65ALERT_DESCRIPTION_RECORD_OVERFLOW
66ALERT_DESCRIPTION_DECOMPRESSION_FAILURE
67ALERT_DESCRIPTION_HANDSHAKE_FAILURE
68ALERT_DESCRIPTION_BAD_CERTIFICATE
69ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE
70ALERT_DESCRIPTION_CERTIFICATE_REVOKED
71ALERT_DESCRIPTION_CERTIFICATE_EXPIRED
72ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN
73ALERT_DESCRIPTION_ILLEGAL_PARAMETER
74ALERT_DESCRIPTION_UNKNOWN_CA
75ALERT_DESCRIPTION_ACCESS_DENIED
76ALERT_DESCRIPTION_DECODE_ERROR
77ALERT_DESCRIPTION_DECRYPT_ERROR
78ALERT_DESCRIPTION_PROTOCOL_VERSION
79ALERT_DESCRIPTION_INSUFFICIENT_SECURITY
80ALERT_DESCRIPTION_INTERNAL_ERROR
81ALERT_DESCRIPTION_USER_CANCELLED
82ALERT_DESCRIPTION_NO_RENEGOTIATION
83ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION
84ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE
85ALERT_DESCRIPTION_UNRECOGNIZED_NAME
86ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE
87ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE
88ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000089"""
90
Christian Heimesc5f05e42008-02-23 17:40:11 +000091import textwrap
Benjamin Petersondaeb9252014-08-20 14:14:50 -050092import re
93import sys
94import os
95from collections import namedtuple
96from contextlib import closing
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000097
98import _ssl # if we can't import it, let the error propagate
Bill Janssen98d19da2007-09-10 21:51:02 +000099
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000100from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500101from _ssl import _SSLContext
102from _ssl import (
103 SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
104 SSLSyscallError, SSLEOFError,
105 )
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000106from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500107from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
Victor Stinner7c906672015-01-06 13:53:37 +0100108from _ssl import RAND_status, RAND_add
109try:
110 from _ssl import RAND_egd
111except ImportError:
112 # LibreSSL does not provide RAND_egd
113 pass
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500114
115def _import_symbols(prefix):
116 for n in dir(_ssl):
117 if n.startswith(prefix):
118 globals()[n] = getattr(_ssl, n)
119
120_import_symbols('OP_')
121_import_symbols('ALERT_DESCRIPTION_')
122_import_symbols('SSL_ERROR_')
123_import_symbols('PROTOCOL_')
Benjamin Petersonb10d50e2015-03-04 23:18:57 -0500124_import_symbols('VERIFY_')
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500125
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -0500126from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500127
128from _ssl import _OPENSSL_API_VERSION
129
Christian Heimesc2fc7c42016-09-05 23:37:13 +0200130_PROTOCOL_NAMES = {value: name for name, value in globals().items()
131 if name.startswith('PROTOCOL_')
132 and name != 'PROTOCOL_SSLv23'}
133PROTOCOL_SSLv23 = PROTOCOL_TLS
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500134
Victor Stinnerb1241f92011-05-10 01:52:03 +0200135try:
Antoine Pitroud76088d2012-01-03 22:46:48 +0100136 _SSLv2_IF_EXISTS = PROTOCOL_SSLv2
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500137except NameError:
Antoine Pitroud76088d2012-01-03 22:46:48 +0100138 _SSLv2_IF_EXISTS = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000139
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000140from socket import socket, _fileobject, _delegate_methods, error as socket_error
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500141if sys.platform == "win32":
142 from _ssl import enum_certificates, enum_crls
143
144from socket import socket, AF_INET, SOCK_STREAM, create_connection
145from socket import SOL_SOCKET, SO_TYPE
Bill Janssen296a59d2007-09-16 22:06:00 +0000146import base64 # for DER-to-PEM translation
Antoine Pitrou278d6652010-04-26 17:23:33 +0000147import errno
Steve Dower90c9b402016-05-26 12:17:21 -0700148import warnings
Bill Janssen98d19da2007-09-10 21:51:02 +0000149
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500150if _ssl.HAS_TLS_UNIQUE:
151 CHANNEL_BINDING_TYPES = ['tls-unique']
152else:
153 CHANNEL_BINDING_TYPES = []
154
Christian Heimesd988f422016-09-06 20:06:47 +0200155
Antoine Pitroud76088d2012-01-03 22:46:48 +0100156# Disable weak or insecure ciphers by default
157# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500158# Enable a better set of ciphers by default
159# This list has been explicitly chosen to:
160# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
161# * Prefer ECDHE over DHE for better performance
Christian Heimesd988f422016-09-06 20:06:47 +0200162# * Prefer AEAD over CBC for better performance and security
163# * Prefer AES-GCM over ChaCha20 because most platforms have AES-NI
164# (ChaCha20 needs OpenSSL 1.1.0 or patched 1.0.2)
165# * Prefer any AES-GCM and ChaCha20 over any AES-CBC for better
166# performance and security
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500167# * Then Use HIGH cipher suites as a fallback
Christian Heimesd988f422016-09-06 20:06:47 +0200168# * Disable NULL authentication, NULL encryption, 3DES and MD5 MACs
169# for security reasons
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500170_DEFAULT_CIPHERS = (
Christian Heimesd988f422016-09-06 20:06:47 +0200171 'ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:'
172 'ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:'
173 '!aNULL:!eNULL:!MD5:!3DES'
174 )
Antoine Pitroud76088d2012-01-03 22:46:48 +0100175
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500176# Restricted and more secure ciphers for the server side
177# This list has been explicitly chosen to:
178# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
179# * Prefer ECDHE over DHE for better performance
Christian Heimesd988f422016-09-06 20:06:47 +0200180# * Prefer AEAD over CBC for better performance and security
181# * Prefer AES-GCM over ChaCha20 because most platforms have AES-NI
182# * Prefer any AES-GCM and ChaCha20 over any AES-CBC for better
183# performance and security
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500184# * Then Use HIGH cipher suites as a fallback
Christian Heimesd988f422016-09-06 20:06:47 +0200185# * Disable NULL authentication, NULL encryption, MD5 MACs, DSS, RC4, and
186# 3DES for security reasons
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500187_RESTRICTED_SERVER_CIPHERS = (
Christian Heimesd988f422016-09-06 20:06:47 +0200188 'ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:'
189 'ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:'
190 '!aNULL:!eNULL:!MD5:!DSS:!RC4:!3DES'
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500191)
192
193
194class CertificateError(ValueError):
195 pass
196
197
198def _dnsname_match(dn, hostname, max_wildcards=1):
199 """Matching according to RFC 6125, section 6.4.3
200
201 http://tools.ietf.org/html/rfc6125#section-6.4.3
202 """
203 pats = []
204 if not dn:
205 return False
206
207 pieces = dn.split(r'.')
208 leftmost = pieces[0]
209 remainder = pieces[1:]
210
211 wildcards = leftmost.count('*')
212 if wildcards > max_wildcards:
213 # Issue #17980: avoid denials of service by refusing more
214 # than one wildcard per fragment. A survery of established
215 # policy among SSL implementations showed it to be a
216 # reasonable choice.
217 raise CertificateError(
218 "too many wildcards in certificate DNS name: " + repr(dn))
219
220 # speed up common case w/o wildcards
221 if not wildcards:
222 return dn.lower() == hostname.lower()
223
224 # RFC 6125, section 6.4.3, subitem 1.
225 # The client SHOULD NOT attempt to match a presented identifier in which
226 # the wildcard character comprises a label other than the left-most label.
227 if leftmost == '*':
228 # When '*' is a fragment by itself, it matches a non-empty dotless
229 # fragment.
230 pats.append('[^.]+')
231 elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
232 # RFC 6125, section 6.4.3, subitem 3.
233 # The client SHOULD NOT attempt to match a presented identifier
234 # where the wildcard character is embedded within an A-label or
235 # U-label of an internationalized domain name.
236 pats.append(re.escape(leftmost))
237 else:
238 # Otherwise, '*' matches any dotless string, e.g. www*
239 pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
240
241 # add the remaining fragments, ignore any wildcards
242 for frag in remainder:
243 pats.append(re.escape(frag))
244
245 pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
246 return pat.match(hostname)
247
248
249def match_hostname(cert, hostname):
250 """Verify that *cert* (in decoded format as returned by
251 SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
252 rules are followed, but IP addresses are not accepted for *hostname*.
253
254 CertificateError is raised on failure. On success, the function
255 returns nothing.
256 """
257 if not cert:
258 raise ValueError("empty or no certificate, match_hostname needs a "
259 "SSL socket or SSL context with either "
260 "CERT_OPTIONAL or CERT_REQUIRED")
261 dnsnames = []
262 san = cert.get('subjectAltName', ())
263 for key, value in san:
264 if key == 'DNS':
265 if _dnsname_match(value, hostname):
266 return
267 dnsnames.append(value)
268 if not dnsnames:
269 # The subject is only checked when there is no dNSName entry
270 # in subjectAltName
271 for sub in cert.get('subject', ()):
272 for key, value in sub:
273 # XXX according to RFC 2818, the most specific Common Name
274 # must be used.
275 if key == 'commonName':
276 if _dnsname_match(value, hostname):
277 return
278 dnsnames.append(value)
279 if len(dnsnames) > 1:
280 raise CertificateError("hostname %r "
281 "doesn't match either of %s"
282 % (hostname, ', '.join(map(repr, dnsnames))))
283 elif len(dnsnames) == 1:
284 raise CertificateError("hostname %r "
285 "doesn't match %r"
286 % (hostname, dnsnames[0]))
287 else:
288 raise CertificateError("no appropriate commonName or "
289 "subjectAltName fields were found")
290
291
292DefaultVerifyPaths = namedtuple("DefaultVerifyPaths",
293 "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env "
294 "openssl_capath")
295
296def get_default_verify_paths():
297 """Return paths to default cafile and capath.
298 """
299 parts = _ssl.get_default_verify_paths()
300
301 # environment vars shadow paths
302 cafile = os.environ.get(parts[0], parts[1])
303 capath = os.environ.get(parts[2], parts[3])
304
305 return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None,
306 capath if os.path.isdir(capath) else None,
307 *parts)
308
309
310class _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")):
311 """ASN.1 object identifier lookup
312 """
313 __slots__ = ()
314
315 def __new__(cls, oid):
316 return super(_ASN1Object, cls).__new__(cls, *_txt2obj(oid, name=False))
317
318 @classmethod
319 def fromnid(cls, nid):
320 """Create _ASN1Object from OpenSSL numeric ID
321 """
322 return super(_ASN1Object, cls).__new__(cls, *_nid2obj(nid))
323
324 @classmethod
325 def fromname(cls, name):
326 """Create _ASN1Object from short name, long name or OID
327 """
328 return super(_ASN1Object, cls).__new__(cls, *_txt2obj(name, name=True))
329
330
331class Purpose(_ASN1Object):
332 """SSLContext purpose flags with X509v3 Extended Key Usage objects
333 """
334
335Purpose.SERVER_AUTH = Purpose('1.3.6.1.5.5.7.3.1')
336Purpose.CLIENT_AUTH = Purpose('1.3.6.1.5.5.7.3.2')
337
338
339class SSLContext(_SSLContext):
340 """An SSLContext holds various SSL-related configuration options and
341 data, such as certificates and possibly a private key."""
342
343 __slots__ = ('protocol', '__weakref__')
344 _windows_cert_stores = ("CA", "ROOT")
345
346 def __new__(cls, protocol, *args, **kwargs):
347 self = _SSLContext.__new__(cls, protocol)
348 if protocol != _SSLv2_IF_EXISTS:
349 self.set_ciphers(_DEFAULT_CIPHERS)
350 return self
351
352 def __init__(self, protocol):
353 self.protocol = protocol
354
355 def wrap_socket(self, sock, server_side=False,
356 do_handshake_on_connect=True,
357 suppress_ragged_eofs=True,
358 server_hostname=None):
359 return SSLSocket(sock=sock, server_side=server_side,
360 do_handshake_on_connect=do_handshake_on_connect,
361 suppress_ragged_eofs=suppress_ragged_eofs,
362 server_hostname=server_hostname,
363 _context=self)
364
365 def set_npn_protocols(self, npn_protocols):
366 protos = bytearray()
367 for protocol in npn_protocols:
368 b = protocol.encode('ascii')
369 if len(b) == 0 or len(b) > 255:
370 raise SSLError('NPN protocols must be 1 to 255 in length')
371 protos.append(len(b))
372 protos.extend(b)
373
374 self._set_npn_protocols(protos)
375
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -0500376 def set_alpn_protocols(self, alpn_protocols):
377 protos = bytearray()
378 for protocol in alpn_protocols:
379 b = protocol.encode('ascii')
380 if len(b) == 0 or len(b) > 255:
381 raise SSLError('ALPN protocols must be 1 to 255 in length')
382 protos.append(len(b))
383 protos.extend(b)
384
385 self._set_alpn_protocols(protos)
386
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500387 def _load_windows_store_certs(self, storename, purpose):
388 certs = bytearray()
Steve Dower90c9b402016-05-26 12:17:21 -0700389 try:
390 for cert, encoding, trust in enum_certificates(storename):
391 # CA certs are never PKCS#7 encoded
392 if encoding == "x509_asn":
393 if trust is True or purpose.oid in trust:
394 certs.extend(cert)
395 except OSError:
396 warnings.warn("unable to enumerate Windows certificate store")
Steve Dower9cb20742016-03-17 15:02:19 -0700397 if certs:
398 self.load_verify_locations(cadata=certs)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500399 return certs
400
401 def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
402 if not isinstance(purpose, _ASN1Object):
403 raise TypeError(purpose)
404 if sys.platform == "win32":
405 for storename in self._windows_cert_stores:
406 self._load_windows_store_certs(storename, purpose)
Benjamin Peterson0b30a2b2014-10-03 17:27:05 -0400407 self.set_default_verify_paths()
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500408
409
410def create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None,
411 capath=None, cadata=None):
412 """Create a SSLContext object with default settings.
413
414 NOTE: The protocol and settings may change anytime without prior
415 deprecation. The values represent a fair balance between maximum
416 compatibility and security.
417 """
418 if not isinstance(purpose, _ASN1Object):
419 raise TypeError(purpose)
420
Christian Heimesc2fc7c42016-09-05 23:37:13 +0200421 context = SSLContext(PROTOCOL_TLS)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500422
423 # SSLv2 considered harmful.
424 context.options |= OP_NO_SSLv2
425
426 # SSLv3 has problematic security and is only required for really old
427 # clients such as IE6 on Windows XP
428 context.options |= OP_NO_SSLv3
429
430 # disable compression to prevent CRIME attacks (OpenSSL 1.0+)
431 context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0)
432
433 if purpose == Purpose.SERVER_AUTH:
434 # verify certs and host name in client mode
435 context.verify_mode = CERT_REQUIRED
436 context.check_hostname = True
437 elif purpose == Purpose.CLIENT_AUTH:
438 # Prefer the server's ciphers by default so that we get stronger
439 # encryption
440 context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
441
442 # Use single use keys in order to improve forward secrecy
443 context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0)
444 context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0)
445
446 # disallow ciphers with known vulnerabilities
447 context.set_ciphers(_RESTRICTED_SERVER_CIPHERS)
448
449 if cafile or capath or cadata:
450 context.load_verify_locations(cafile, capath, cadata)
451 elif context.verify_mode != CERT_NONE:
452 # no explicit cafile, capath or cadata but the verify mode is
453 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
454 # root CA certificates for the given purpose. This may fail silently.
455 context.load_default_certs(purpose)
456 return context
457
Christian Heimesc2fc7c42016-09-05 23:37:13 +0200458def _create_unverified_context(protocol=PROTOCOL_TLS, cert_reqs=None,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500459 check_hostname=False, purpose=Purpose.SERVER_AUTH,
460 certfile=None, keyfile=None,
461 cafile=None, capath=None, cadata=None):
462 """Create a SSLContext object for Python stdlib modules
463
464 All Python stdlib modules shall use this function to create SSLContext
465 objects in order to keep common settings in one place. The configuration
466 is less restrict than create_default_context()'s to increase backward
467 compatibility.
468 """
469 if not isinstance(purpose, _ASN1Object):
470 raise TypeError(purpose)
471
472 context = SSLContext(protocol)
473 # SSLv2 considered harmful.
474 context.options |= OP_NO_SSLv2
Antoine Pitrou95b61642014-10-17 19:28:30 +0200475 # SSLv3 has problematic security and is only required for really old
476 # clients such as IE6 on Windows XP
477 context.options |= OP_NO_SSLv3
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500478
479 if cert_reqs is not None:
480 context.verify_mode = cert_reqs
481 context.check_hostname = check_hostname
482
483 if keyfile and not certfile:
484 raise ValueError("certfile must be specified")
485 if certfile or keyfile:
486 context.load_cert_chain(certfile, keyfile)
487
488 # load CA root certs
489 if cafile or capath or cadata:
490 context.load_verify_locations(cafile, capath, cadata)
491 elif context.verify_mode != CERT_NONE:
492 # no explicit cafile, capath or cadata but the verify mode is
493 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
494 # root CA certificates for the given purpose. This may fail silently.
495 context.load_default_certs(purpose)
496
497 return context
Antoine Pitroud76088d2012-01-03 22:46:48 +0100498
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600499# Backwards compatibility alias, even though it's not a public name.
500_create_stdlib_context = _create_unverified_context
501
Nick Coghlandbcd4572016-03-20 22:39:15 +1000502# PEP 493: Verify HTTPS by default, but allow envvar to override that
503_https_verify_envvar = 'PYTHONHTTPSVERIFY'
504
505def _get_https_context_factory():
506 if not sys.flags.ignore_environment:
507 config_setting = os.environ.get(_https_verify_envvar)
508 if config_setting == '0':
509 return _create_unverified_context
510 return create_default_context
511
512_create_default_https_context = _get_https_context_factory()
513
514# PEP 493: "private" API to configure HTTPS defaults without monkeypatching
515def _https_verify_certificates(enable=True):
516 """Verify server HTTPS certificates by default?"""
517 global _create_default_https_context
518 if enable:
519 _create_default_https_context = create_default_context
520 else:
521 _create_default_https_context = _create_unverified_context
522
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600523
Ezio Melottib01f5e62010-01-18 09:10:26 +0000524class SSLSocket(socket):
Bill Janssen426ea0a2007-08-29 22:35:05 +0000525 """This class implements a subtype of socket.socket that wraps
526 the underlying OS socket in an SSL context when necessary, and
527 provides read and write methods over that channel."""
528
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500529 def __init__(self, sock=None, keyfile=None, certfile=None,
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000530 server_side=False, cert_reqs=CERT_NONE,
Christian Heimesc2fc7c42016-09-05 23:37:13 +0200531 ssl_version=PROTOCOL_TLS, ca_certs=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000532 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500533 family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
534 suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
535 server_hostname=None,
536 _context=None):
537
Benjamin Peterson5f6b89b2014-11-23 11:16:48 -0600538 self._makefile_refs = 0
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500539 if _context:
540 self._context = _context
541 else:
542 if server_side and not certfile:
543 raise ValueError("certfile must be specified for server-side "
544 "operations")
545 if keyfile and not certfile:
546 raise ValueError("certfile must be specified")
547 if certfile and not keyfile:
548 keyfile = certfile
549 self._context = SSLContext(ssl_version)
550 self._context.verify_mode = cert_reqs
551 if ca_certs:
552 self._context.load_verify_locations(ca_certs)
553 if certfile:
554 self._context.load_cert_chain(certfile, keyfile)
555 if npn_protocols:
556 self._context.set_npn_protocols(npn_protocols)
557 if ciphers:
558 self._context.set_ciphers(ciphers)
559 self.keyfile = keyfile
560 self.certfile = certfile
561 self.cert_reqs = cert_reqs
562 self.ssl_version = ssl_version
563 self.ca_certs = ca_certs
564 self.ciphers = ciphers
Antoine Pitrou63cc99d2013-12-28 17:26:33 +0100565 # Can't use sock.type as other flags (such as SOCK_NONBLOCK) get
566 # mixed in.
567 if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
568 raise NotImplementedError("only stream sockets are supported")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000569 socket.__init__(self, _sock=sock._sock)
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000570 # The initializer for socket overrides the methods send(), recv(), etc.
571 # in the instancce, which we don't need -- but we want to provide the
572 # methods defined in SSLSocket.
573 for attr in _delegate_methods:
574 try:
575 delattr(self, attr)
576 except AttributeError:
577 pass
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500578 if server_side and server_hostname:
579 raise ValueError("server_hostname can only be specified "
580 "in client mode")
581 if self._context.check_hostname and not server_hostname:
Benjamin Peterson31aa69e2014-11-23 20:13:31 -0600582 raise ValueError("check_hostname requires server_hostname")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500583 self.server_side = server_side
584 self.server_hostname = server_hostname
Bill Janssen934b16d2008-06-28 22:19:33 +0000585 self.do_handshake_on_connect = do_handshake_on_connect
586 self.suppress_ragged_eofs = suppress_ragged_eofs
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500587
588 # See if we are connected
589 try:
590 self.getpeername()
591 except socket_error as e:
592 if e.errno != errno.ENOTCONN:
593 raise
594 connected = False
595 else:
596 connected = True
597
598 self._closed = False
599 self._sslobj = None
600 self._connected = connected
601 if connected:
602 # create the SSL object
603 try:
604 self._sslobj = self._context._wrap_socket(self._sock, server_side,
605 server_hostname, ssl_sock=self)
606 if do_handshake_on_connect:
607 timeout = self.gettimeout()
608 if timeout == 0.0:
609 # non-blocking
610 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
611 self.do_handshake()
612
613 except (OSError, ValueError):
614 self.close()
615 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000616
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500617 @property
618 def context(self):
619 return self._context
Bill Janssen24bccf22007-08-30 17:07:28 +0000620
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500621 @context.setter
622 def context(self, ctx):
623 self._context = ctx
624 self._sslobj.context = ctx
625
626 def dup(self):
627 raise NotImplemented("Can't dup() %s instances" %
628 self.__class__.__name__)
629
630 def _checkClosed(self, msg=None):
631 # raise an exception here if you wish to check for spurious closes
632 pass
633
634 def _check_connected(self):
635 if not self._connected:
636 # getpeername() will raise ENOTCONN if the socket is really
637 # not connected; note that we can be connected even without
638 # _connected being set, e.g. if connect() first returned
639 # EAGAIN.
640 self.getpeername()
641
Martin Panterd524b702016-03-28 00:22:09 +0000642 def read(self, len=1024, buffer=None):
Bill Janssen24bccf22007-08-30 17:07:28 +0000643 """Read up to LEN bytes and return them.
644 Return zero-length string on EOF."""
645
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500646 self._checkClosed()
647 if not self._sslobj:
648 raise ValueError("Read on closed or unwrapped SSL socket.")
Bill Janssen934b16d2008-06-28 22:19:33 +0000649 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500650 if buffer is not None:
651 v = self._sslobj.read(len, buffer)
652 else:
Martin Panterd524b702016-03-28 00:22:09 +0000653 v = self._sslobj.read(len)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500654 return v
655 except SSLError as x:
Bill Janssen934b16d2008-06-28 22:19:33 +0000656 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500657 if buffer is not None:
658 return 0
659 else:
660 return b''
Bill Janssen934b16d2008-06-28 22:19:33 +0000661 else:
662 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000663
664 def write(self, data):
Bill Janssen24bccf22007-08-30 17:07:28 +0000665 """Write DATA to the underlying SSL channel. Returns
666 number of bytes of DATA actually transmitted."""
667
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500668 self._checkClosed()
669 if not self._sslobj:
670 raise ValueError("Write on closed or unwrapped SSL socket.")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000671 return self._sslobj.write(data)
672
Bill Janssen98d19da2007-09-10 21:51:02 +0000673 def getpeercert(self, binary_form=False):
Bill Janssen24bccf22007-08-30 17:07:28 +0000674 """Returns a formatted version of the data in the
675 certificate provided by the other end of the SSL channel.
676 Return None if no certificate was provided, {} if a
677 certificate was provided, but not validated."""
678
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500679 self._checkClosed()
680 self._check_connected()
Bill Janssen98d19da2007-09-10 21:51:02 +0000681 return self._sslobj.peer_certificate(binary_form)
682
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500683 def selected_npn_protocol(self):
684 self._checkClosed()
685 if not self._sslobj or not _ssl.HAS_NPN:
686 return None
687 else:
688 return self._sslobj.selected_npn_protocol()
Bill Janssen98d19da2007-09-10 21:51:02 +0000689
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -0500690 def selected_alpn_protocol(self):
691 self._checkClosed()
692 if not self._sslobj or not _ssl.HAS_ALPN:
693 return None
694 else:
695 return self._sslobj.selected_alpn_protocol()
696
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500697 def cipher(self):
698 self._checkClosed()
Bill Janssen98d19da2007-09-10 21:51:02 +0000699 if not self._sslobj:
700 return None
701 else:
702 return self._sslobj.cipher()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000703
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500704 def compression(self):
705 self._checkClosed()
706 if not self._sslobj:
707 return None
708 else:
709 return self._sslobj.compression()
710
Ezio Melottib01f5e62010-01-18 09:10:26 +0000711 def send(self, data, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500712 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000713 if self._sslobj:
714 if flags != 0:
715 raise ValueError(
716 "non-zero flags not allowed in calls to send() on %s" %
717 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500718 try:
719 v = self._sslobj.write(data)
720 except SSLError as x:
721 if x.args[0] == SSL_ERROR_WANT_READ:
722 return 0
723 elif x.args[0] == SSL_ERROR_WANT_WRITE:
724 return 0
Bill Janssen934b16d2008-06-28 22:19:33 +0000725 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500726 raise
727 else:
728 return v
Bill Janssen426ea0a2007-08-29 22:35:05 +0000729 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000730 return self._sock.send(data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000731
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000732 def sendto(self, data, flags_or_addr, addr=None):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500733 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000734 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000735 raise ValueError("sendto not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000736 self.__class__)
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000737 elif addr is None:
738 return self._sock.sendto(data, flags_or_addr)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000739 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000740 return self._sock.sendto(data, flags_or_addr, addr)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000741
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500742
Ezio Melottib01f5e62010-01-18 09:10:26 +0000743 def sendall(self, data, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500744 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000745 if self._sslobj:
746 if flags != 0:
747 raise ValueError(
748 "non-zero flags not allowed in calls to sendall() on %s" %
749 self.__class__)
Bill Janssen934b16d2008-06-28 22:19:33 +0000750 amount = len(data)
751 count = 0
752 while (count < amount):
753 v = self.send(data[count:])
754 count += v
755 return amount
Bill Janssen426ea0a2007-08-29 22:35:05 +0000756 else:
757 return socket.sendall(self, data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000758
Ezio Melottib01f5e62010-01-18 09:10:26 +0000759 def recv(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500760 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000761 if self._sslobj:
762 if flags != 0:
763 raise ValueError(
Antoine Pitrou448da712010-03-21 19:33:38 +0000764 "non-zero flags not allowed in calls to recv() on %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000765 self.__class__)
Antoine Pitrou448da712010-03-21 19:33:38 +0000766 return self.read(buflen)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000767 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000768 return self._sock.recv(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000769
Ezio Melottib01f5e62010-01-18 09:10:26 +0000770 def recv_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500771 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000772 if buffer and (nbytes is None):
773 nbytes = len(buffer)
774 elif nbytes is None:
775 nbytes = 1024
776 if self._sslobj:
777 if flags != 0:
778 raise ValueError(
779 "non-zero flags not allowed in calls to recv_into() on %s" %
780 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500781 return self.read(nbytes, buffer)
Bill Janssen61c001a2008-09-08 16:37:24 +0000782 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000783 return self._sock.recv_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000784
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000785 def recvfrom(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500786 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000787 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000788 raise ValueError("recvfrom not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000789 self.__class__)
790 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000791 return self._sock.recvfrom(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000792
Ezio Melottib01f5e62010-01-18 09:10:26 +0000793 def recvfrom_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500794 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000795 if self._sslobj:
796 raise ValueError("recvfrom_into not allowed on instances of %s" %
797 self.__class__)
798 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000799 return self._sock.recvfrom_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000800
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500801
Ezio Melottib01f5e62010-01-18 09:10:26 +0000802 def pending(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500803 self._checkClosed()
Bill Janssen934b16d2008-06-28 22:19:33 +0000804 if self._sslobj:
805 return self._sslobj.pending()
806 else:
807 return 0
808
Ezio Melottib01f5e62010-01-18 09:10:26 +0000809 def shutdown(self, how):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500810 self._checkClosed()
Bill Janssen296a59d2007-09-16 22:06:00 +0000811 self._sslobj = None
Bill Janssen426ea0a2007-08-29 22:35:05 +0000812 socket.shutdown(self, how)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000813
Ezio Melottib01f5e62010-01-18 09:10:26 +0000814 def close(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000815 if self._makefile_refs < 1:
816 self._sslobj = None
817 socket.close(self)
818 else:
819 self._makefile_refs -= 1
820
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500821 def unwrap(self):
822 if self._sslobj:
823 s = self._sslobj.shutdown()
824 self._sslobj = None
825 return s
826 else:
827 raise ValueError("No SSL wrapper around " + str(self))
Bill Janssen934b16d2008-06-28 22:19:33 +0000828
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500829 def _real_close(self):
830 self._sslobj = None
831 socket._real_close(self)
832
833 def do_handshake(self, block=False):
Bill Janssen934b16d2008-06-28 22:19:33 +0000834 """Perform a TLS/SSL handshake."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500835 self._check_connected()
836 timeout = self.gettimeout()
837 try:
838 if timeout == 0.0 and block:
839 self.settimeout(None)
840 self._sslobj.do_handshake()
841 finally:
842 self.settimeout(timeout)
Bill Janssen934b16d2008-06-28 22:19:33 +0000843
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500844 if self.context.check_hostname:
845 if not self.server_hostname:
846 raise ValueError("check_hostname needs server_hostname "
847 "argument")
848 match_hostname(self.getpeercert(), self.server_hostname)
Bill Janssen934b16d2008-06-28 22:19:33 +0000849
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500850 def _real_connect(self, addr, connect_ex):
851 if self.server_side:
852 raise ValueError("can't connect in server-side mode")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000853 # Here we assume that the socket is client-side, and not
854 # connected at the time of the call. We connect it, then wrap it.
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000855 if self._connected:
Bill Janssen98d19da2007-09-10 21:51:02 +0000856 raise ValueError("attempt to connect already-connected SSLSocket!")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500857 self._sslobj = self.context._wrap_socket(self._sock, False, self.server_hostname, ssl_sock=self)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000858 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500859 if connect_ex:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100860 rc = socket.connect_ex(self, addr)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000861 else:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100862 rc = None
863 socket.connect(self, addr)
864 if not rc:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500865 self._connected = True
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100866 if self.do_handshake_on_connect:
867 self.do_handshake()
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100868 return rc
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500869 except (OSError, ValueError):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100870 self._sslobj = None
871 raise
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000872
873 def connect(self, addr):
874 """Connects to remote ADDR, and then wraps the connection in
875 an SSL channel."""
876 self._real_connect(addr, False)
877
878 def connect_ex(self, addr):
879 """Connects to remote ADDR, and then wraps the connection in
880 an SSL channel."""
881 return self._real_connect(addr, True)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000882
883 def accept(self):
Bill Janssen24bccf22007-08-30 17:07:28 +0000884 """Accepts a new connection from a remote client, and returns
885 a tuple containing that new connection wrapped with a server-side
886 SSL channel, and the address of the remote client."""
887
Bill Janssen426ea0a2007-08-29 22:35:05 +0000888 newsock, addr = socket.accept(self)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500889 newsock = self.context.wrap_socket(newsock,
890 do_handshake_on_connect=self.do_handshake_on_connect,
891 suppress_ragged_eofs=self.suppress_ragged_eofs,
892 server_side=True)
893 return newsock, addr
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000894
Bill Janssen296a59d2007-09-16 22:06:00 +0000895 def makefile(self, mode='r', bufsize=-1):
896
Bill Janssen61c001a2008-09-08 16:37:24 +0000897 """Make and return a file-like object that
898 works with the SSL connection. Just use the code
899 from the socket module."""
Bill Janssen296a59d2007-09-16 22:06:00 +0000900
Bill Janssen934b16d2008-06-28 22:19:33 +0000901 self._makefile_refs += 1
Antoine Pitroub558f172010-04-23 23:25:45 +0000902 # close=True so as to decrement the reference count when done with
903 # the file-like object.
904 return _fileobject(self, mode, bufsize, close=True)
Bill Janssen296a59d2007-09-16 22:06:00 +0000905
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500906 def get_channel_binding(self, cb_type="tls-unique"):
907 """Get channel binding data for current connection. Raise ValueError
908 if the requested `cb_type` is not supported. Return bytes of the data
909 or None if the data is not available (e.g. before the handshake).
910 """
911 if cb_type not in CHANNEL_BINDING_TYPES:
912 raise ValueError("Unsupported channel binding type")
913 if cb_type != "tls-unique":
914 raise NotImplementedError(
915 "{0} channel binding type not implemented"
916 .format(cb_type))
917 if self._sslobj is None:
918 return None
919 return self._sslobj.tls_unique_cb()
Bill Janssen296a59d2007-09-16 22:06:00 +0000920
Alex Gaynore98205d2014-09-04 13:33:22 -0700921 def version(self):
922 """
923 Return a string identifying the protocol version used by the
924 current SSL channel, or None if there is no established channel.
925 """
926 if self._sslobj is None:
927 return None
928 return self._sslobj.version()
929
Bill Janssen296a59d2007-09-16 22:06:00 +0000930
Bill Janssen98d19da2007-09-10 21:51:02 +0000931def wrap_socket(sock, keyfile=None, certfile=None,
932 server_side=False, cert_reqs=CERT_NONE,
Christian Heimesc2fc7c42016-09-05 23:37:13 +0200933 ssl_version=PROTOCOL_TLS, ca_certs=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000934 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500935 suppress_ragged_eofs=True,
936 ciphers=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000937
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500938 return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000939 server_side=server_side, cert_reqs=cert_reqs,
Bill Janssen934b16d2008-06-28 22:19:33 +0000940 ssl_version=ssl_version, ca_certs=ca_certs,
941 do_handshake_on_connect=do_handshake_on_connect,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000942 suppress_ragged_eofs=suppress_ragged_eofs,
943 ciphers=ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000944
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000945# some utility functions
946
947def cert_time_to_seconds(cert_time):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500948 """Return the time in seconds since the Epoch, given the timestring
949 representing the "notBefore" or "notAfter" date from a certificate
950 in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale).
Bill Janssen24bccf22007-08-30 17:07:28 +0000951
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500952 "notBefore" or "notAfter" dates must use UTC (RFC 5280).
Bill Janssen24bccf22007-08-30 17:07:28 +0000953
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500954 Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
955 UTC should be specified as GMT (see ASN1_TIME_print())
956 """
957 from time import strptime
958 from calendar import timegm
959
960 months = (
961 "Jan","Feb","Mar","Apr","May","Jun",
962 "Jul","Aug","Sep","Oct","Nov","Dec"
963 )
964 time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT
965 try:
966 month_number = months.index(cert_time[:3].title()) + 1
967 except ValueError:
968 raise ValueError('time data %r does not match '
969 'format "%%b%s"' % (cert_time, time_format))
970 else:
971 # found valid month
972 tt = strptime(cert_time[3:], time_format)
973 # return an integer, the previous mktime()-based implementation
974 # returned a float (fractional seconds are always zero here).
975 return timegm((tt[0], month_number) + tt[2:6])
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000976
Bill Janssen296a59d2007-09-16 22:06:00 +0000977PEM_HEADER = "-----BEGIN CERTIFICATE-----"
978PEM_FOOTER = "-----END CERTIFICATE-----"
979
980def DER_cert_to_PEM_cert(der_cert_bytes):
Bill Janssen296a59d2007-09-16 22:06:00 +0000981 """Takes a certificate in binary DER format and returns the
982 PEM version of it as a string."""
983
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500984 f = base64.standard_b64encode(der_cert_bytes).decode('ascii')
985 return (PEM_HEADER + '\n' +
986 textwrap.fill(f, 64) + '\n' +
987 PEM_FOOTER + '\n')
Bill Janssen296a59d2007-09-16 22:06:00 +0000988
989def PEM_cert_to_DER_cert(pem_cert_string):
Bill Janssen296a59d2007-09-16 22:06:00 +0000990 """Takes a certificate in ASCII PEM format and returns the
991 DER-encoded version of it as a byte sequence"""
992
993 if not pem_cert_string.startswith(PEM_HEADER):
994 raise ValueError("Invalid PEM encoding; must start with %s"
995 % PEM_HEADER)
996 if not pem_cert_string.strip().endswith(PEM_FOOTER):
997 raise ValueError("Invalid PEM encoding; must end with %s"
998 % PEM_FOOTER)
999 d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001000 return base64.decodestring(d.encode('ASCII', 'strict'))
Bill Janssen296a59d2007-09-16 22:06:00 +00001001
Christian Heimesc2fc7c42016-09-05 23:37:13 +02001002def get_server_certificate(addr, ssl_version=PROTOCOL_TLS, ca_certs=None):
Bill Janssen296a59d2007-09-16 22:06:00 +00001003 """Retrieve the certificate from the server at the specified address,
1004 and return it as a PEM-encoded string.
1005 If 'ca_certs' is specified, validate the server cert against it.
1006 If 'ssl_version' is specified, use it in the connection attempt."""
1007
1008 host, port = addr
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001009 if ca_certs is not None:
Bill Janssen296a59d2007-09-16 22:06:00 +00001010 cert_reqs = CERT_REQUIRED
1011 else:
1012 cert_reqs = CERT_NONE
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001013 context = _create_stdlib_context(ssl_version,
1014 cert_reqs=cert_reqs,
1015 cafile=ca_certs)
1016 with closing(create_connection(addr)) as sock:
1017 with closing(context.wrap_socket(sock)) as sslsock:
1018 dercert = sslsock.getpeercert(True)
Bill Janssen296a59d2007-09-16 22:06:00 +00001019 return DER_cert_to_PEM_cert(dercert)
1020
Ezio Melottib01f5e62010-01-18 09:10:26 +00001021def get_protocol_name(protocol_code):
Victor Stinnerb1241f92011-05-10 01:52:03 +02001022 return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
Bill Janssen296a59d2007-09-16 22:06:00 +00001023
1024
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001025# a replacement for the old socket.ssl function
1026
Ezio Melottib01f5e62010-01-18 09:10:26 +00001027def sslwrap_simple(sock, keyfile=None, certfile=None):
Bill Janssen24bccf22007-08-30 17:07:28 +00001028 """A replacement for the old socket.ssl function. Designed
1029 for compability with Python 2.5 and earlier. Will disappear in
1030 Python 3.0."""
Bill Jansseneb257ac2008-09-29 18:56:38 +00001031 if hasattr(sock, "_sock"):
1032 sock = sock._sock
1033
Benjamin Peterson2f334562014-10-01 23:53:01 -04001034 ctx = SSLContext(PROTOCOL_SSLv23)
1035 if keyfile or certfile:
1036 ctx.load_cert_chain(certfile, keyfile)
1037 ssl_sock = ctx._wrap_socket(sock, server_side=False)
Bill Jansseneb257ac2008-09-29 18:56:38 +00001038 try:
1039 sock.getpeername()
Benjamin Peterson941db4d2008-12-31 04:08:55 +00001040 except socket_error:
Bill Jansseneb257ac2008-09-29 18:56:38 +00001041 # no, no connection yet
1042 pass
1043 else:
1044 # yes, do the handshake
1045 ssl_sock.do_handshake()
1046
Bill Janssen934b16d2008-06-28 22:19:33 +00001047 return ssl_sock