blob: 0f822277e96e38eb9b9542b73c73b3bd8a02cde4 [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
54PROTOCOL_TLSv1
Benjamin Petersondaeb9252014-08-20 14:14:50 -050055PROTOCOL_TLSv1_1
56PROTOCOL_TLSv1_2
57
58The following constants identify various SSL alert message descriptions as per
59http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6
60
61ALERT_DESCRIPTION_CLOSE_NOTIFY
62ALERT_DESCRIPTION_UNEXPECTED_MESSAGE
63ALERT_DESCRIPTION_BAD_RECORD_MAC
64ALERT_DESCRIPTION_RECORD_OVERFLOW
65ALERT_DESCRIPTION_DECOMPRESSION_FAILURE
66ALERT_DESCRIPTION_HANDSHAKE_FAILURE
67ALERT_DESCRIPTION_BAD_CERTIFICATE
68ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE
69ALERT_DESCRIPTION_CERTIFICATE_REVOKED
70ALERT_DESCRIPTION_CERTIFICATE_EXPIRED
71ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN
72ALERT_DESCRIPTION_ILLEGAL_PARAMETER
73ALERT_DESCRIPTION_UNKNOWN_CA
74ALERT_DESCRIPTION_ACCESS_DENIED
75ALERT_DESCRIPTION_DECODE_ERROR
76ALERT_DESCRIPTION_DECRYPT_ERROR
77ALERT_DESCRIPTION_PROTOCOL_VERSION
78ALERT_DESCRIPTION_INSUFFICIENT_SECURITY
79ALERT_DESCRIPTION_INTERNAL_ERROR
80ALERT_DESCRIPTION_USER_CANCELLED
81ALERT_DESCRIPTION_NO_RENEGOTIATION
82ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION
83ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE
84ALERT_DESCRIPTION_UNRECOGNIZED_NAME
85ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE
86ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE
87ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000088"""
89
Christian Heimesc5f05e42008-02-23 17:40:11 +000090import textwrap
Benjamin Petersondaeb9252014-08-20 14:14:50 -050091import re
92import sys
93import os
94from collections import namedtuple
95from contextlib import closing
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000096
97import _ssl # if we can't import it, let the error propagate
Bill Janssen98d19da2007-09-10 21:51:02 +000098
Antoine Pitrouf9de5342010-04-05 21:35:07 +000099from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500100from _ssl import _SSLContext
101from _ssl import (
102 SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
103 SSLSyscallError, SSLEOFError,
104 )
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000105from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500106from _ssl import (VERIFY_DEFAULT, VERIFY_CRL_CHECK_LEAF, VERIFY_CRL_CHECK_CHAIN,
107 VERIFY_X509_STRICT)
108from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
Bill Janssen98d19da2007-09-10 21:51:02 +0000109from _ssl import RAND_status, RAND_egd, RAND_add
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500110
111def _import_symbols(prefix):
112 for n in dir(_ssl):
113 if n.startswith(prefix):
114 globals()[n] = getattr(_ssl, n)
115
116_import_symbols('OP_')
117_import_symbols('ALERT_DESCRIPTION_')
118_import_symbols('SSL_ERROR_')
119_import_symbols('PROTOCOL_')
120
121from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN
122
123from _ssl import _OPENSSL_API_VERSION
124
125_PROTOCOL_NAMES = {value: name for name, value in globals().items() if name.startswith('PROTOCOL_')}
126
Victor Stinnerb1241f92011-05-10 01:52:03 +0200127try:
Antoine Pitroud76088d2012-01-03 22:46:48 +0100128 _SSLv2_IF_EXISTS = PROTOCOL_SSLv2
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500129except NameError:
Antoine Pitroud76088d2012-01-03 22:46:48 +0100130 _SSLv2_IF_EXISTS = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000131
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000132from socket import socket, _fileobject, _delegate_methods, error as socket_error
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500133if sys.platform == "win32":
134 from _ssl import enum_certificates, enum_crls
135
136from socket import socket, AF_INET, SOCK_STREAM, create_connection
137from socket import SOL_SOCKET, SO_TYPE
Bill Janssen296a59d2007-09-16 22:06:00 +0000138import base64 # for DER-to-PEM translation
Antoine Pitrou278d6652010-04-26 17:23:33 +0000139import errno
Bill Janssen98d19da2007-09-10 21:51:02 +0000140
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500141if _ssl.HAS_TLS_UNIQUE:
142 CHANNEL_BINDING_TYPES = ['tls-unique']
143else:
144 CHANNEL_BINDING_TYPES = []
145
Antoine Pitroud76088d2012-01-03 22:46:48 +0100146# Disable weak or insecure ciphers by default
147# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500148# Enable a better set of ciphers by default
149# This list has been explicitly chosen to:
150# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
151# * Prefer ECDHE over DHE for better performance
152# * Prefer any AES-GCM over any AES-CBC for better performance and security
153# * Then Use HIGH cipher suites as a fallback
154# * Then Use 3DES as fallback which is secure but slow
155# * Finally use RC4 as a fallback which is problematic but needed for
156# compatibility some times.
157# * Disable NULL authentication, NULL encryption, and MD5 MACs for security
158# reasons
159_DEFAULT_CIPHERS = (
160 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
161 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:ECDH+RC4:'
162 'DH+RC4:RSA+RC4:!aNULL:!eNULL:!MD5'
163)
Antoine Pitroud76088d2012-01-03 22:46:48 +0100164
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500165# Restricted and more secure ciphers for the server side
166# This list has been explicitly chosen to:
167# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
168# * Prefer ECDHE over DHE for better performance
169# * Prefer any AES-GCM over any AES-CBC for better performance and security
170# * Then Use HIGH cipher suites as a fallback
171# * Then Use 3DES as fallback which is secure but slow
172# * Disable NULL authentication, NULL encryption, MD5 MACs, DSS, and RC4 for
173# security reasons
174_RESTRICTED_SERVER_CIPHERS = (
175 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
176 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
177 '!eNULL:!MD5:!DSS:!RC4'
178)
179
180
181class CertificateError(ValueError):
182 pass
183
184
185def _dnsname_match(dn, hostname, max_wildcards=1):
186 """Matching according to RFC 6125, section 6.4.3
187
188 http://tools.ietf.org/html/rfc6125#section-6.4.3
189 """
190 pats = []
191 if not dn:
192 return False
193
194 pieces = dn.split(r'.')
195 leftmost = pieces[0]
196 remainder = pieces[1:]
197
198 wildcards = leftmost.count('*')
199 if wildcards > max_wildcards:
200 # Issue #17980: avoid denials of service by refusing more
201 # than one wildcard per fragment. A survery of established
202 # policy among SSL implementations showed it to be a
203 # reasonable choice.
204 raise CertificateError(
205 "too many wildcards in certificate DNS name: " + repr(dn))
206
207 # speed up common case w/o wildcards
208 if not wildcards:
209 return dn.lower() == hostname.lower()
210
211 # RFC 6125, section 6.4.3, subitem 1.
212 # The client SHOULD NOT attempt to match a presented identifier in which
213 # the wildcard character comprises a label other than the left-most label.
214 if leftmost == '*':
215 # When '*' is a fragment by itself, it matches a non-empty dotless
216 # fragment.
217 pats.append('[^.]+')
218 elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
219 # RFC 6125, section 6.4.3, subitem 3.
220 # The client SHOULD NOT attempt to match a presented identifier
221 # where the wildcard character is embedded within an A-label or
222 # U-label of an internationalized domain name.
223 pats.append(re.escape(leftmost))
224 else:
225 # Otherwise, '*' matches any dotless string, e.g. www*
226 pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
227
228 # add the remaining fragments, ignore any wildcards
229 for frag in remainder:
230 pats.append(re.escape(frag))
231
232 pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
233 return pat.match(hostname)
234
235
236def match_hostname(cert, hostname):
237 """Verify that *cert* (in decoded format as returned by
238 SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
239 rules are followed, but IP addresses are not accepted for *hostname*.
240
241 CertificateError is raised on failure. On success, the function
242 returns nothing.
243 """
244 if not cert:
245 raise ValueError("empty or no certificate, match_hostname needs a "
246 "SSL socket or SSL context with either "
247 "CERT_OPTIONAL or CERT_REQUIRED")
248 dnsnames = []
249 san = cert.get('subjectAltName', ())
250 for key, value in san:
251 if key == 'DNS':
252 if _dnsname_match(value, hostname):
253 return
254 dnsnames.append(value)
255 if not dnsnames:
256 # The subject is only checked when there is no dNSName entry
257 # in subjectAltName
258 for sub in cert.get('subject', ()):
259 for key, value in sub:
260 # XXX according to RFC 2818, the most specific Common Name
261 # must be used.
262 if key == 'commonName':
263 if _dnsname_match(value, hostname):
264 return
265 dnsnames.append(value)
266 if len(dnsnames) > 1:
267 raise CertificateError("hostname %r "
268 "doesn't match either of %s"
269 % (hostname, ', '.join(map(repr, dnsnames))))
270 elif len(dnsnames) == 1:
271 raise CertificateError("hostname %r "
272 "doesn't match %r"
273 % (hostname, dnsnames[0]))
274 else:
275 raise CertificateError("no appropriate commonName or "
276 "subjectAltName fields were found")
277
278
279DefaultVerifyPaths = namedtuple("DefaultVerifyPaths",
280 "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env "
281 "openssl_capath")
282
283def get_default_verify_paths():
284 """Return paths to default cafile and capath.
285 """
286 parts = _ssl.get_default_verify_paths()
287
288 # environment vars shadow paths
289 cafile = os.environ.get(parts[0], parts[1])
290 capath = os.environ.get(parts[2], parts[3])
291
292 return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None,
293 capath if os.path.isdir(capath) else None,
294 *parts)
295
296
297class _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")):
298 """ASN.1 object identifier lookup
299 """
300 __slots__ = ()
301
302 def __new__(cls, oid):
303 return super(_ASN1Object, cls).__new__(cls, *_txt2obj(oid, name=False))
304
305 @classmethod
306 def fromnid(cls, nid):
307 """Create _ASN1Object from OpenSSL numeric ID
308 """
309 return super(_ASN1Object, cls).__new__(cls, *_nid2obj(nid))
310
311 @classmethod
312 def fromname(cls, name):
313 """Create _ASN1Object from short name, long name or OID
314 """
315 return super(_ASN1Object, cls).__new__(cls, *_txt2obj(name, name=True))
316
317
318class Purpose(_ASN1Object):
319 """SSLContext purpose flags with X509v3 Extended Key Usage objects
320 """
321
322Purpose.SERVER_AUTH = Purpose('1.3.6.1.5.5.7.3.1')
323Purpose.CLIENT_AUTH = Purpose('1.3.6.1.5.5.7.3.2')
324
325
326class SSLContext(_SSLContext):
327 """An SSLContext holds various SSL-related configuration options and
328 data, such as certificates and possibly a private key."""
329
330 __slots__ = ('protocol', '__weakref__')
331 _windows_cert_stores = ("CA", "ROOT")
332
333 def __new__(cls, protocol, *args, **kwargs):
334 self = _SSLContext.__new__(cls, protocol)
335 if protocol != _SSLv2_IF_EXISTS:
336 self.set_ciphers(_DEFAULT_CIPHERS)
337 return self
338
339 def __init__(self, protocol):
340 self.protocol = protocol
341
342 def wrap_socket(self, sock, server_side=False,
343 do_handshake_on_connect=True,
344 suppress_ragged_eofs=True,
345 server_hostname=None):
346 return SSLSocket(sock=sock, server_side=server_side,
347 do_handshake_on_connect=do_handshake_on_connect,
348 suppress_ragged_eofs=suppress_ragged_eofs,
349 server_hostname=server_hostname,
350 _context=self)
351
352 def set_npn_protocols(self, npn_protocols):
353 protos = bytearray()
354 for protocol in npn_protocols:
355 b = protocol.encode('ascii')
356 if len(b) == 0 or len(b) > 255:
357 raise SSLError('NPN protocols must be 1 to 255 in length')
358 protos.append(len(b))
359 protos.extend(b)
360
361 self._set_npn_protocols(protos)
362
363 def _load_windows_store_certs(self, storename, purpose):
364 certs = bytearray()
365 for cert, encoding, trust in enum_certificates(storename):
366 # CA certs are never PKCS#7 encoded
367 if encoding == "x509_asn":
368 if trust is True or purpose.oid in trust:
369 certs.extend(cert)
370 self.load_verify_locations(cadata=certs)
371 return certs
372
373 def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
374 if not isinstance(purpose, _ASN1Object):
375 raise TypeError(purpose)
376 if sys.platform == "win32":
377 for storename in self._windows_cert_stores:
378 self._load_windows_store_certs(storename, purpose)
Benjamin Peterson0b30a2b2014-10-03 17:27:05 -0400379 self.set_default_verify_paths()
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500380
381
382def create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None,
383 capath=None, cadata=None):
384 """Create a SSLContext object with default settings.
385
386 NOTE: The protocol and settings may change anytime without prior
387 deprecation. The values represent a fair balance between maximum
388 compatibility and security.
389 """
390 if not isinstance(purpose, _ASN1Object):
391 raise TypeError(purpose)
392
393 context = SSLContext(PROTOCOL_SSLv23)
394
395 # SSLv2 considered harmful.
396 context.options |= OP_NO_SSLv2
397
398 # SSLv3 has problematic security and is only required for really old
399 # clients such as IE6 on Windows XP
400 context.options |= OP_NO_SSLv3
401
402 # disable compression to prevent CRIME attacks (OpenSSL 1.0+)
403 context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0)
404
405 if purpose == Purpose.SERVER_AUTH:
406 # verify certs and host name in client mode
407 context.verify_mode = CERT_REQUIRED
408 context.check_hostname = True
409 elif purpose == Purpose.CLIENT_AUTH:
410 # Prefer the server's ciphers by default so that we get stronger
411 # encryption
412 context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
413
414 # Use single use keys in order to improve forward secrecy
415 context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0)
416 context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0)
417
418 # disallow ciphers with known vulnerabilities
419 context.set_ciphers(_RESTRICTED_SERVER_CIPHERS)
420
421 if cafile or capath or cadata:
422 context.load_verify_locations(cafile, capath, cadata)
423 elif context.verify_mode != CERT_NONE:
424 # no explicit cafile, capath or cadata but the verify mode is
425 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
426 # root CA certificates for the given purpose. This may fail silently.
427 context.load_default_certs(purpose)
428 return context
429
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600430def _create_unverified_context(protocol=PROTOCOL_SSLv23, cert_reqs=None,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500431 check_hostname=False, purpose=Purpose.SERVER_AUTH,
432 certfile=None, keyfile=None,
433 cafile=None, capath=None, cadata=None):
434 """Create a SSLContext object for Python stdlib modules
435
436 All Python stdlib modules shall use this function to create SSLContext
437 objects in order to keep common settings in one place. The configuration
438 is less restrict than create_default_context()'s to increase backward
439 compatibility.
440 """
441 if not isinstance(purpose, _ASN1Object):
442 raise TypeError(purpose)
443
444 context = SSLContext(protocol)
445 # SSLv2 considered harmful.
446 context.options |= OP_NO_SSLv2
Antoine Pitrou95b61642014-10-17 19:28:30 +0200447 # SSLv3 has problematic security and is only required for really old
448 # clients such as IE6 on Windows XP
449 context.options |= OP_NO_SSLv3
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500450
451 if cert_reqs is not None:
452 context.verify_mode = cert_reqs
453 context.check_hostname = check_hostname
454
455 if keyfile and not certfile:
456 raise ValueError("certfile must be specified")
457 if certfile or keyfile:
458 context.load_cert_chain(certfile, keyfile)
459
460 # load CA root certs
461 if cafile or capath or cadata:
462 context.load_verify_locations(cafile, capath, cadata)
463 elif context.verify_mode != CERT_NONE:
464 # no explicit cafile, capath or cadata but the verify mode is
465 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
466 # root CA certificates for the given purpose. This may fail silently.
467 context.load_default_certs(purpose)
468
469 return context
Antoine Pitroud76088d2012-01-03 22:46:48 +0100470
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600471# Used by http.client if no context is explicitly passed.
472_create_default_https_context = create_default_context
473
474
475# Backwards compatibility alias, even though it's not a public name.
476_create_stdlib_context = _create_unverified_context
477
478
Ezio Melottib01f5e62010-01-18 09:10:26 +0000479class SSLSocket(socket):
Bill Janssen426ea0a2007-08-29 22:35:05 +0000480 """This class implements a subtype of socket.socket that wraps
481 the underlying OS socket in an SSL context when necessary, and
482 provides read and write methods over that channel."""
483
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500484 def __init__(self, sock=None, keyfile=None, certfile=None,
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000485 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen934b16d2008-06-28 22:19:33 +0000486 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
487 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500488 family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
489 suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
490 server_hostname=None,
491 _context=None):
492
Benjamin Peterson5f6b89b2014-11-23 11:16:48 -0600493 self._makefile_refs = 0
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500494 if _context:
495 self._context = _context
496 else:
497 if server_side and not certfile:
498 raise ValueError("certfile must be specified for server-side "
499 "operations")
500 if keyfile and not certfile:
501 raise ValueError("certfile must be specified")
502 if certfile and not keyfile:
503 keyfile = certfile
504 self._context = SSLContext(ssl_version)
505 self._context.verify_mode = cert_reqs
506 if ca_certs:
507 self._context.load_verify_locations(ca_certs)
508 if certfile:
509 self._context.load_cert_chain(certfile, keyfile)
510 if npn_protocols:
511 self._context.set_npn_protocols(npn_protocols)
512 if ciphers:
513 self._context.set_ciphers(ciphers)
514 self.keyfile = keyfile
515 self.certfile = certfile
516 self.cert_reqs = cert_reqs
517 self.ssl_version = ssl_version
518 self.ca_certs = ca_certs
519 self.ciphers = ciphers
Antoine Pitrou63cc99d2013-12-28 17:26:33 +0100520 # Can't use sock.type as other flags (such as SOCK_NONBLOCK) get
521 # mixed in.
522 if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
523 raise NotImplementedError("only stream sockets are supported")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000524 socket.__init__(self, _sock=sock._sock)
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000525 # The initializer for socket overrides the methods send(), recv(), etc.
526 # in the instancce, which we don't need -- but we want to provide the
527 # methods defined in SSLSocket.
528 for attr in _delegate_methods:
529 try:
530 delattr(self, attr)
531 except AttributeError:
532 pass
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500533 if server_side and server_hostname:
534 raise ValueError("server_hostname can only be specified "
535 "in client mode")
536 if self._context.check_hostname and not server_hostname:
Benjamin Peterson31aa69e2014-11-23 20:13:31 -0600537 raise ValueError("check_hostname requires server_hostname")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500538 self.server_side = server_side
539 self.server_hostname = server_hostname
Bill Janssen934b16d2008-06-28 22:19:33 +0000540 self.do_handshake_on_connect = do_handshake_on_connect
541 self.suppress_ragged_eofs = suppress_ragged_eofs
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500542
543 # See if we are connected
544 try:
545 self.getpeername()
546 except socket_error as e:
547 if e.errno != errno.ENOTCONN:
548 raise
549 connected = False
550 else:
551 connected = True
552
553 self._closed = False
554 self._sslobj = None
555 self._connected = connected
556 if connected:
557 # create the SSL object
558 try:
559 self._sslobj = self._context._wrap_socket(self._sock, server_side,
560 server_hostname, ssl_sock=self)
561 if do_handshake_on_connect:
562 timeout = self.gettimeout()
563 if timeout == 0.0:
564 # non-blocking
565 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
566 self.do_handshake()
567
568 except (OSError, ValueError):
569 self.close()
570 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000571
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500572 @property
573 def context(self):
574 return self._context
Bill Janssen24bccf22007-08-30 17:07:28 +0000575
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500576 @context.setter
577 def context(self, ctx):
578 self._context = ctx
579 self._sslobj.context = ctx
580
581 def dup(self):
582 raise NotImplemented("Can't dup() %s instances" %
583 self.__class__.__name__)
584
585 def _checkClosed(self, msg=None):
586 # raise an exception here if you wish to check for spurious closes
587 pass
588
589 def _check_connected(self):
590 if not self._connected:
591 # getpeername() will raise ENOTCONN if the socket is really
592 # not connected; note that we can be connected even without
593 # _connected being set, e.g. if connect() first returned
594 # EAGAIN.
595 self.getpeername()
596
597 def read(self, len=0, buffer=None):
Bill Janssen24bccf22007-08-30 17:07:28 +0000598 """Read up to LEN bytes and return them.
599 Return zero-length string on EOF."""
600
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500601 self._checkClosed()
602 if not self._sslobj:
603 raise ValueError("Read on closed or unwrapped SSL socket.")
Bill Janssen934b16d2008-06-28 22:19:33 +0000604 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500605 if buffer is not None:
606 v = self._sslobj.read(len, buffer)
607 else:
608 v = self._sslobj.read(len or 1024)
609 return v
610 except SSLError as x:
Bill Janssen934b16d2008-06-28 22:19:33 +0000611 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500612 if buffer is not None:
613 return 0
614 else:
615 return b''
Bill Janssen934b16d2008-06-28 22:19:33 +0000616 else:
617 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000618
619 def write(self, data):
Bill Janssen24bccf22007-08-30 17:07:28 +0000620 """Write DATA to the underlying SSL channel. Returns
621 number of bytes of DATA actually transmitted."""
622
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500623 self._checkClosed()
624 if not self._sslobj:
625 raise ValueError("Write on closed or unwrapped SSL socket.")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000626 return self._sslobj.write(data)
627
Bill Janssen98d19da2007-09-10 21:51:02 +0000628 def getpeercert(self, binary_form=False):
Bill Janssen24bccf22007-08-30 17:07:28 +0000629 """Returns a formatted version of the data in the
630 certificate provided by the other end of the SSL channel.
631 Return None if no certificate was provided, {} if a
632 certificate was provided, but not validated."""
633
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500634 self._checkClosed()
635 self._check_connected()
Bill Janssen98d19da2007-09-10 21:51:02 +0000636 return self._sslobj.peer_certificate(binary_form)
637
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500638 def selected_npn_protocol(self):
639 self._checkClosed()
640 if not self._sslobj or not _ssl.HAS_NPN:
641 return None
642 else:
643 return self._sslobj.selected_npn_protocol()
Bill Janssen98d19da2007-09-10 21:51:02 +0000644
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500645 def cipher(self):
646 self._checkClosed()
Bill Janssen98d19da2007-09-10 21:51:02 +0000647 if not self._sslobj:
648 return None
649 else:
650 return self._sslobj.cipher()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000651
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500652 def compression(self):
653 self._checkClosed()
654 if not self._sslobj:
655 return None
656 else:
657 return self._sslobj.compression()
658
Ezio Melottib01f5e62010-01-18 09:10:26 +0000659 def send(self, data, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500660 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000661 if self._sslobj:
662 if flags != 0:
663 raise ValueError(
664 "non-zero flags not allowed in calls to send() on %s" %
665 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500666 try:
667 v = self._sslobj.write(data)
668 except SSLError as x:
669 if x.args[0] == SSL_ERROR_WANT_READ:
670 return 0
671 elif x.args[0] == SSL_ERROR_WANT_WRITE:
672 return 0
Bill Janssen934b16d2008-06-28 22:19:33 +0000673 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500674 raise
675 else:
676 return v
Bill Janssen426ea0a2007-08-29 22:35:05 +0000677 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000678 return self._sock.send(data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000679
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000680 def sendto(self, data, flags_or_addr, addr=None):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500681 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000682 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000683 raise ValueError("sendto not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000684 self.__class__)
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000685 elif addr is None:
686 return self._sock.sendto(data, flags_or_addr)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000687 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000688 return self._sock.sendto(data, flags_or_addr, addr)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000689
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500690
Ezio Melottib01f5e62010-01-18 09:10:26 +0000691 def sendall(self, data, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500692 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000693 if self._sslobj:
694 if flags != 0:
695 raise ValueError(
696 "non-zero flags not allowed in calls to sendall() on %s" %
697 self.__class__)
Bill Janssen934b16d2008-06-28 22:19:33 +0000698 amount = len(data)
699 count = 0
700 while (count < amount):
701 v = self.send(data[count:])
702 count += v
703 return amount
Bill Janssen426ea0a2007-08-29 22:35:05 +0000704 else:
705 return socket.sendall(self, data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000706
Ezio Melottib01f5e62010-01-18 09:10:26 +0000707 def recv(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500708 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000709 if self._sslobj:
710 if flags != 0:
711 raise ValueError(
Antoine Pitrou448da712010-03-21 19:33:38 +0000712 "non-zero flags not allowed in calls to recv() on %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000713 self.__class__)
Antoine Pitrou448da712010-03-21 19:33:38 +0000714 return self.read(buflen)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000715 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000716 return self._sock.recv(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000717
Ezio Melottib01f5e62010-01-18 09:10:26 +0000718 def recv_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500719 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000720 if buffer and (nbytes is None):
721 nbytes = len(buffer)
722 elif nbytes is None:
723 nbytes = 1024
724 if self._sslobj:
725 if flags != 0:
726 raise ValueError(
727 "non-zero flags not allowed in calls to recv_into() on %s" %
728 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500729 return self.read(nbytes, buffer)
Bill Janssen61c001a2008-09-08 16:37:24 +0000730 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000731 return self._sock.recv_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000732
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000733 def recvfrom(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500734 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000735 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000736 raise ValueError("recvfrom not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000737 self.__class__)
738 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000739 return self._sock.recvfrom(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000740
Ezio Melottib01f5e62010-01-18 09:10:26 +0000741 def recvfrom_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500742 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000743 if self._sslobj:
744 raise ValueError("recvfrom_into not allowed on instances of %s" %
745 self.__class__)
746 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000747 return self._sock.recvfrom_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000748
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500749
Ezio Melottib01f5e62010-01-18 09:10:26 +0000750 def pending(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500751 self._checkClosed()
Bill Janssen934b16d2008-06-28 22:19:33 +0000752 if self._sslobj:
753 return self._sslobj.pending()
754 else:
755 return 0
756
Ezio Melottib01f5e62010-01-18 09:10:26 +0000757 def shutdown(self, how):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500758 self._checkClosed()
Bill Janssen296a59d2007-09-16 22:06:00 +0000759 self._sslobj = None
Bill Janssen426ea0a2007-08-29 22:35:05 +0000760 socket.shutdown(self, how)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000761
Ezio Melottib01f5e62010-01-18 09:10:26 +0000762 def close(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000763 if self._makefile_refs < 1:
764 self._sslobj = None
765 socket.close(self)
766 else:
767 self._makefile_refs -= 1
768
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500769 def unwrap(self):
770 if self._sslobj:
771 s = self._sslobj.shutdown()
772 self._sslobj = None
773 return s
774 else:
775 raise ValueError("No SSL wrapper around " + str(self))
Bill Janssen934b16d2008-06-28 22:19:33 +0000776
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500777 def _real_close(self):
778 self._sslobj = None
779 socket._real_close(self)
780
781 def do_handshake(self, block=False):
Bill Janssen934b16d2008-06-28 22:19:33 +0000782 """Perform a TLS/SSL handshake."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500783 self._check_connected()
784 timeout = self.gettimeout()
785 try:
786 if timeout == 0.0 and block:
787 self.settimeout(None)
788 self._sslobj.do_handshake()
789 finally:
790 self.settimeout(timeout)
Bill Janssen934b16d2008-06-28 22:19:33 +0000791
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500792 if self.context.check_hostname:
793 if not self.server_hostname:
794 raise ValueError("check_hostname needs server_hostname "
795 "argument")
796 match_hostname(self.getpeercert(), self.server_hostname)
Bill Janssen934b16d2008-06-28 22:19:33 +0000797
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500798 def _real_connect(self, addr, connect_ex):
799 if self.server_side:
800 raise ValueError("can't connect in server-side mode")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000801 # Here we assume that the socket is client-side, and not
802 # connected at the time of the call. We connect it, then wrap it.
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000803 if self._connected:
Bill Janssen98d19da2007-09-10 21:51:02 +0000804 raise ValueError("attempt to connect already-connected SSLSocket!")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500805 self._sslobj = self.context._wrap_socket(self._sock, False, self.server_hostname, ssl_sock=self)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000806 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500807 if connect_ex:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100808 rc = socket.connect_ex(self, addr)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000809 else:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100810 rc = None
811 socket.connect(self, addr)
812 if not rc:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500813 self._connected = True
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100814 if self.do_handshake_on_connect:
815 self.do_handshake()
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100816 return rc
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500817 except (OSError, ValueError):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100818 self._sslobj = None
819 raise
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000820
821 def connect(self, addr):
822 """Connects to remote ADDR, and then wraps the connection in
823 an SSL channel."""
824 self._real_connect(addr, False)
825
826 def connect_ex(self, addr):
827 """Connects to remote ADDR, and then wraps the connection in
828 an SSL channel."""
829 return self._real_connect(addr, True)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000830
831 def accept(self):
Bill Janssen24bccf22007-08-30 17:07:28 +0000832 """Accepts a new connection from a remote client, and returns
833 a tuple containing that new connection wrapped with a server-side
834 SSL channel, and the address of the remote client."""
835
Bill Janssen426ea0a2007-08-29 22:35:05 +0000836 newsock, addr = socket.accept(self)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500837 newsock = self.context.wrap_socket(newsock,
838 do_handshake_on_connect=self.do_handshake_on_connect,
839 suppress_ragged_eofs=self.suppress_ragged_eofs,
840 server_side=True)
841 return newsock, addr
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000842
Bill Janssen296a59d2007-09-16 22:06:00 +0000843 def makefile(self, mode='r', bufsize=-1):
844
Bill Janssen61c001a2008-09-08 16:37:24 +0000845 """Make and return a file-like object that
846 works with the SSL connection. Just use the code
847 from the socket module."""
Bill Janssen296a59d2007-09-16 22:06:00 +0000848
Bill Janssen934b16d2008-06-28 22:19:33 +0000849 self._makefile_refs += 1
Antoine Pitroub558f172010-04-23 23:25:45 +0000850 # close=True so as to decrement the reference count when done with
851 # the file-like object.
852 return _fileobject(self, mode, bufsize, close=True)
Bill Janssen296a59d2007-09-16 22:06:00 +0000853
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500854 def get_channel_binding(self, cb_type="tls-unique"):
855 """Get channel binding data for current connection. Raise ValueError
856 if the requested `cb_type` is not supported. Return bytes of the data
857 or None if the data is not available (e.g. before the handshake).
858 """
859 if cb_type not in CHANNEL_BINDING_TYPES:
860 raise ValueError("Unsupported channel binding type")
861 if cb_type != "tls-unique":
862 raise NotImplementedError(
863 "{0} channel binding type not implemented"
864 .format(cb_type))
865 if self._sslobj is None:
866 return None
867 return self._sslobj.tls_unique_cb()
Bill Janssen296a59d2007-09-16 22:06:00 +0000868
Alex Gaynore98205d2014-09-04 13:33:22 -0700869 def version(self):
870 """
871 Return a string identifying the protocol version used by the
872 current SSL channel, or None if there is no established channel.
873 """
874 if self._sslobj is None:
875 return None
876 return self._sslobj.version()
877
Bill Janssen296a59d2007-09-16 22:06:00 +0000878
Bill Janssen98d19da2007-09-10 21:51:02 +0000879def wrap_socket(sock, keyfile=None, certfile=None,
880 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen934b16d2008-06-28 22:19:33 +0000881 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
882 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500883 suppress_ragged_eofs=True,
884 ciphers=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000885
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500886 return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000887 server_side=server_side, cert_reqs=cert_reqs,
Bill Janssen934b16d2008-06-28 22:19:33 +0000888 ssl_version=ssl_version, ca_certs=ca_certs,
889 do_handshake_on_connect=do_handshake_on_connect,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000890 suppress_ragged_eofs=suppress_ragged_eofs,
891 ciphers=ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000892
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000893# some utility functions
894
895def cert_time_to_seconds(cert_time):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500896 """Return the time in seconds since the Epoch, given the timestring
897 representing the "notBefore" or "notAfter" date from a certificate
898 in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale).
Bill Janssen24bccf22007-08-30 17:07:28 +0000899
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500900 "notBefore" or "notAfter" dates must use UTC (RFC 5280).
Bill Janssen24bccf22007-08-30 17:07:28 +0000901
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500902 Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
903 UTC should be specified as GMT (see ASN1_TIME_print())
904 """
905 from time import strptime
906 from calendar import timegm
907
908 months = (
909 "Jan","Feb","Mar","Apr","May","Jun",
910 "Jul","Aug","Sep","Oct","Nov","Dec"
911 )
912 time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT
913 try:
914 month_number = months.index(cert_time[:3].title()) + 1
915 except ValueError:
916 raise ValueError('time data %r does not match '
917 'format "%%b%s"' % (cert_time, time_format))
918 else:
919 # found valid month
920 tt = strptime(cert_time[3:], time_format)
921 # return an integer, the previous mktime()-based implementation
922 # returned a float (fractional seconds are always zero here).
923 return timegm((tt[0], month_number) + tt[2:6])
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000924
Bill Janssen296a59d2007-09-16 22:06:00 +0000925PEM_HEADER = "-----BEGIN CERTIFICATE-----"
926PEM_FOOTER = "-----END CERTIFICATE-----"
927
928def DER_cert_to_PEM_cert(der_cert_bytes):
Bill Janssen296a59d2007-09-16 22:06:00 +0000929 """Takes a certificate in binary DER format and returns the
930 PEM version of it as a string."""
931
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500932 f = base64.standard_b64encode(der_cert_bytes).decode('ascii')
933 return (PEM_HEADER + '\n' +
934 textwrap.fill(f, 64) + '\n' +
935 PEM_FOOTER + '\n')
Bill Janssen296a59d2007-09-16 22:06:00 +0000936
937def PEM_cert_to_DER_cert(pem_cert_string):
Bill Janssen296a59d2007-09-16 22:06:00 +0000938 """Takes a certificate in ASCII PEM format and returns the
939 DER-encoded version of it as a byte sequence"""
940
941 if not pem_cert_string.startswith(PEM_HEADER):
942 raise ValueError("Invalid PEM encoding; must start with %s"
943 % PEM_HEADER)
944 if not pem_cert_string.strip().endswith(PEM_FOOTER):
945 raise ValueError("Invalid PEM encoding; must end with %s"
946 % PEM_FOOTER)
947 d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500948 return base64.decodestring(d.encode('ASCII', 'strict'))
Bill Janssen296a59d2007-09-16 22:06:00 +0000949
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500950def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000951 """Retrieve the certificate from the server at the specified address,
952 and return it as a PEM-encoded string.
953 If 'ca_certs' is specified, validate the server cert against it.
954 If 'ssl_version' is specified, use it in the connection attempt."""
955
956 host, port = addr
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500957 if ca_certs is not None:
Bill Janssen296a59d2007-09-16 22:06:00 +0000958 cert_reqs = CERT_REQUIRED
959 else:
960 cert_reqs = CERT_NONE
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500961 context = _create_stdlib_context(ssl_version,
962 cert_reqs=cert_reqs,
963 cafile=ca_certs)
964 with closing(create_connection(addr)) as sock:
965 with closing(context.wrap_socket(sock)) as sslsock:
966 dercert = sslsock.getpeercert(True)
Bill Janssen296a59d2007-09-16 22:06:00 +0000967 return DER_cert_to_PEM_cert(dercert)
968
Ezio Melottib01f5e62010-01-18 09:10:26 +0000969def get_protocol_name(protocol_code):
Victor Stinnerb1241f92011-05-10 01:52:03 +0200970 return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
Bill Janssen296a59d2007-09-16 22:06:00 +0000971
972
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000973# a replacement for the old socket.ssl function
974
Ezio Melottib01f5e62010-01-18 09:10:26 +0000975def sslwrap_simple(sock, keyfile=None, certfile=None):
Bill Janssen24bccf22007-08-30 17:07:28 +0000976 """A replacement for the old socket.ssl function. Designed
977 for compability with Python 2.5 and earlier. Will disappear in
978 Python 3.0."""
Bill Jansseneb257ac2008-09-29 18:56:38 +0000979 if hasattr(sock, "_sock"):
980 sock = sock._sock
981
Benjamin Peterson2f334562014-10-01 23:53:01 -0400982 ctx = SSLContext(PROTOCOL_SSLv23)
983 if keyfile or certfile:
984 ctx.load_cert_chain(certfile, keyfile)
985 ssl_sock = ctx._wrap_socket(sock, server_side=False)
Bill Jansseneb257ac2008-09-29 18:56:38 +0000986 try:
987 sock.getpeername()
Benjamin Peterson941db4d2008-12-31 04:08:55 +0000988 except socket_error:
Bill Jansseneb257ac2008-09-29 18:56:38 +0000989 # no, no connection yet
990 pass
991 else:
992 # yes, do the handshake
993 ssl_sock.do_handshake()
994
Bill Janssen934b16d2008-06-28 22:19:33 +0000995 return ssl_sock