blob: 5df6ed3f1645a4bd6f77fcaa880544af102ae627 [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 txt2obj as _txt2obj, nid2obj as _nid2obj
Victor Stinner7c906672015-01-06 13:53:37 +0100107from _ssl import RAND_status, RAND_add
108try:
109 from _ssl import RAND_egd
110except ImportError:
111 # LibreSSL does not provide RAND_egd
112 pass
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500113
114def _import_symbols(prefix):
115 for n in dir(_ssl):
116 if n.startswith(prefix):
117 globals()[n] = getattr(_ssl, n)
118
119_import_symbols('OP_')
120_import_symbols('ALERT_DESCRIPTION_')
121_import_symbols('SSL_ERROR_')
122_import_symbols('PROTOCOL_')
Benjamin Petersonb10d50e2015-03-04 23:18:57 -0500123_import_symbols('VERIFY_')
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500124
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -0500125from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500126
127from _ssl import _OPENSSL_API_VERSION
128
129_PROTOCOL_NAMES = {value: name for name, value in globals().items() if name.startswith('PROTOCOL_')}
130
Victor Stinnerb1241f92011-05-10 01:52:03 +0200131try:
Antoine Pitroud76088d2012-01-03 22:46:48 +0100132 _SSLv2_IF_EXISTS = PROTOCOL_SSLv2
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500133except NameError:
Antoine Pitroud76088d2012-01-03 22:46:48 +0100134 _SSLv2_IF_EXISTS = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000135
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000136from socket import socket, _fileobject, _delegate_methods, error as socket_error
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500137if sys.platform == "win32":
138 from _ssl import enum_certificates, enum_crls
139
140from socket import socket, AF_INET, SOCK_STREAM, create_connection
141from socket import SOL_SOCKET, SO_TYPE
Bill Janssen296a59d2007-09-16 22:06:00 +0000142import base64 # for DER-to-PEM translation
Antoine Pitrou278d6652010-04-26 17:23:33 +0000143import errno
Bill Janssen98d19da2007-09-10 21:51:02 +0000144
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500145if _ssl.HAS_TLS_UNIQUE:
146 CHANNEL_BINDING_TYPES = ['tls-unique']
147else:
148 CHANNEL_BINDING_TYPES = []
149
Antoine Pitroud76088d2012-01-03 22:46:48 +0100150# Disable weak or insecure ciphers by default
151# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500152# Enable a better set of ciphers by default
153# This list has been explicitly chosen to:
154# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
155# * Prefer ECDHE over DHE for better performance
156# * Prefer any AES-GCM over any AES-CBC for better performance and security
157# * Then Use HIGH cipher suites as a fallback
158# * Then Use 3DES as fallback which is secure but slow
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500159# * Disable NULL authentication, NULL encryption, and MD5 MACs for security
160# reasons
161_DEFAULT_CIPHERS = (
162 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
Benjamin Petersona0dd7dc2015-02-19 17:57:08 -0500163 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
164 '!eNULL:!MD5'
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500165)
Antoine Pitroud76088d2012-01-03 22:46:48 +0100166
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500167# Restricted and more secure ciphers for the server side
168# This list has been explicitly chosen to:
169# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
170# * Prefer ECDHE over DHE for better performance
171# * Prefer any AES-GCM over any AES-CBC for better performance and security
172# * Then Use HIGH cipher suites as a fallback
173# * Then Use 3DES as fallback which is secure but slow
174# * Disable NULL authentication, NULL encryption, MD5 MACs, DSS, and RC4 for
175# security reasons
176_RESTRICTED_SERVER_CIPHERS = (
177 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
178 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
179 '!eNULL:!MD5:!DSS:!RC4'
180)
181
182
183class CertificateError(ValueError):
184 pass
185
186
187def _dnsname_match(dn, hostname, max_wildcards=1):
188 """Matching according to RFC 6125, section 6.4.3
189
190 http://tools.ietf.org/html/rfc6125#section-6.4.3
191 """
192 pats = []
193 if not dn:
194 return False
195
196 pieces = dn.split(r'.')
197 leftmost = pieces[0]
198 remainder = pieces[1:]
199
200 wildcards = leftmost.count('*')
201 if wildcards > max_wildcards:
202 # Issue #17980: avoid denials of service by refusing more
203 # than one wildcard per fragment. A survery of established
204 # policy among SSL implementations showed it to be a
205 # reasonable choice.
206 raise CertificateError(
207 "too many wildcards in certificate DNS name: " + repr(dn))
208
209 # speed up common case w/o wildcards
210 if not wildcards:
211 return dn.lower() == hostname.lower()
212
213 # RFC 6125, section 6.4.3, subitem 1.
214 # The client SHOULD NOT attempt to match a presented identifier in which
215 # the wildcard character comprises a label other than the left-most label.
216 if leftmost == '*':
217 # When '*' is a fragment by itself, it matches a non-empty dotless
218 # fragment.
219 pats.append('[^.]+')
220 elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
221 # RFC 6125, section 6.4.3, subitem 3.
222 # The client SHOULD NOT attempt to match a presented identifier
223 # where the wildcard character is embedded within an A-label or
224 # U-label of an internationalized domain name.
225 pats.append(re.escape(leftmost))
226 else:
227 # Otherwise, '*' matches any dotless string, e.g. www*
228 pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
229
230 # add the remaining fragments, ignore any wildcards
231 for frag in remainder:
232 pats.append(re.escape(frag))
233
234 pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
235 return pat.match(hostname)
236
237
238def match_hostname(cert, hostname):
239 """Verify that *cert* (in decoded format as returned by
240 SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
241 rules are followed, but IP addresses are not accepted for *hostname*.
242
243 CertificateError is raised on failure. On success, the function
244 returns nothing.
245 """
246 if not cert:
247 raise ValueError("empty or no certificate, match_hostname needs a "
248 "SSL socket or SSL context with either "
249 "CERT_OPTIONAL or CERT_REQUIRED")
250 dnsnames = []
251 san = cert.get('subjectAltName', ())
252 for key, value in san:
253 if key == 'DNS':
254 if _dnsname_match(value, hostname):
255 return
256 dnsnames.append(value)
257 if not dnsnames:
258 # The subject is only checked when there is no dNSName entry
259 # in subjectAltName
260 for sub in cert.get('subject', ()):
261 for key, value in sub:
262 # XXX according to RFC 2818, the most specific Common Name
263 # must be used.
264 if key == 'commonName':
265 if _dnsname_match(value, hostname):
266 return
267 dnsnames.append(value)
268 if len(dnsnames) > 1:
269 raise CertificateError("hostname %r "
270 "doesn't match either of %s"
271 % (hostname, ', '.join(map(repr, dnsnames))))
272 elif len(dnsnames) == 1:
273 raise CertificateError("hostname %r "
274 "doesn't match %r"
275 % (hostname, dnsnames[0]))
276 else:
277 raise CertificateError("no appropriate commonName or "
278 "subjectAltName fields were found")
279
280
281DefaultVerifyPaths = namedtuple("DefaultVerifyPaths",
282 "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env "
283 "openssl_capath")
284
285def get_default_verify_paths():
286 """Return paths to default cafile and capath.
287 """
288 parts = _ssl.get_default_verify_paths()
289
290 # environment vars shadow paths
291 cafile = os.environ.get(parts[0], parts[1])
292 capath = os.environ.get(parts[2], parts[3])
293
294 return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None,
295 capath if os.path.isdir(capath) else None,
296 *parts)
297
298
299class _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")):
300 """ASN.1 object identifier lookup
301 """
302 __slots__ = ()
303
304 def __new__(cls, oid):
305 return super(_ASN1Object, cls).__new__(cls, *_txt2obj(oid, name=False))
306
307 @classmethod
308 def fromnid(cls, nid):
309 """Create _ASN1Object from OpenSSL numeric ID
310 """
311 return super(_ASN1Object, cls).__new__(cls, *_nid2obj(nid))
312
313 @classmethod
314 def fromname(cls, name):
315 """Create _ASN1Object from short name, long name or OID
316 """
317 return super(_ASN1Object, cls).__new__(cls, *_txt2obj(name, name=True))
318
319
320class Purpose(_ASN1Object):
321 """SSLContext purpose flags with X509v3 Extended Key Usage objects
322 """
323
324Purpose.SERVER_AUTH = Purpose('1.3.6.1.5.5.7.3.1')
325Purpose.CLIENT_AUTH = Purpose('1.3.6.1.5.5.7.3.2')
326
327
328class SSLContext(_SSLContext):
329 """An SSLContext holds various SSL-related configuration options and
330 data, such as certificates and possibly a private key."""
331
332 __slots__ = ('protocol', '__weakref__')
333 _windows_cert_stores = ("CA", "ROOT")
334
335 def __new__(cls, protocol, *args, **kwargs):
336 self = _SSLContext.__new__(cls, protocol)
337 if protocol != _SSLv2_IF_EXISTS:
338 self.set_ciphers(_DEFAULT_CIPHERS)
339 return self
340
341 def __init__(self, protocol):
342 self.protocol = protocol
343
344 def wrap_socket(self, sock, server_side=False,
345 do_handshake_on_connect=True,
346 suppress_ragged_eofs=True,
347 server_hostname=None):
348 return SSLSocket(sock=sock, server_side=server_side,
349 do_handshake_on_connect=do_handshake_on_connect,
350 suppress_ragged_eofs=suppress_ragged_eofs,
351 server_hostname=server_hostname,
352 _context=self)
353
354 def set_npn_protocols(self, npn_protocols):
355 protos = bytearray()
356 for protocol in npn_protocols:
357 b = protocol.encode('ascii')
358 if len(b) == 0 or len(b) > 255:
359 raise SSLError('NPN protocols must be 1 to 255 in length')
360 protos.append(len(b))
361 protos.extend(b)
362
363 self._set_npn_protocols(protos)
364
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -0500365 def set_alpn_protocols(self, alpn_protocols):
366 protos = bytearray()
367 for protocol in alpn_protocols:
368 b = protocol.encode('ascii')
369 if len(b) == 0 or len(b) > 255:
370 raise SSLError('ALPN protocols must be 1 to 255 in length')
371 protos.append(len(b))
372 protos.extend(b)
373
374 self._set_alpn_protocols(protos)
375
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500376 def _load_windows_store_certs(self, storename, purpose):
377 certs = bytearray()
378 for cert, encoding, trust in enum_certificates(storename):
379 # CA certs are never PKCS#7 encoded
380 if encoding == "x509_asn":
381 if trust is True or purpose.oid in trust:
382 certs.extend(cert)
383 self.load_verify_locations(cadata=certs)
384 return certs
385
386 def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
387 if not isinstance(purpose, _ASN1Object):
388 raise TypeError(purpose)
389 if sys.platform == "win32":
390 for storename in self._windows_cert_stores:
391 self._load_windows_store_certs(storename, purpose)
Benjamin Peterson0b30a2b2014-10-03 17:27:05 -0400392 self.set_default_verify_paths()
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500393
394
395def create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None,
396 capath=None, cadata=None):
397 """Create a SSLContext object with default settings.
398
399 NOTE: The protocol and settings may change anytime without prior
400 deprecation. The values represent a fair balance between maximum
401 compatibility and security.
402 """
403 if not isinstance(purpose, _ASN1Object):
404 raise TypeError(purpose)
405
406 context = SSLContext(PROTOCOL_SSLv23)
407
408 # SSLv2 considered harmful.
409 context.options |= OP_NO_SSLv2
410
411 # SSLv3 has problematic security and is only required for really old
412 # clients such as IE6 on Windows XP
413 context.options |= OP_NO_SSLv3
414
415 # disable compression to prevent CRIME attacks (OpenSSL 1.0+)
416 context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0)
417
418 if purpose == Purpose.SERVER_AUTH:
419 # verify certs and host name in client mode
420 context.verify_mode = CERT_REQUIRED
421 context.check_hostname = True
422 elif purpose == Purpose.CLIENT_AUTH:
423 # Prefer the server's ciphers by default so that we get stronger
424 # encryption
425 context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
426
427 # Use single use keys in order to improve forward secrecy
428 context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0)
429 context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0)
430
431 # disallow ciphers with known vulnerabilities
432 context.set_ciphers(_RESTRICTED_SERVER_CIPHERS)
433
434 if cafile or capath or cadata:
435 context.load_verify_locations(cafile, capath, cadata)
436 elif context.verify_mode != CERT_NONE:
437 # no explicit cafile, capath or cadata but the verify mode is
438 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
439 # root CA certificates for the given purpose. This may fail silently.
440 context.load_default_certs(purpose)
441 return context
442
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600443def _create_unverified_context(protocol=PROTOCOL_SSLv23, cert_reqs=None,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500444 check_hostname=False, purpose=Purpose.SERVER_AUTH,
445 certfile=None, keyfile=None,
446 cafile=None, capath=None, cadata=None):
447 """Create a SSLContext object for Python stdlib modules
448
449 All Python stdlib modules shall use this function to create SSLContext
450 objects in order to keep common settings in one place. The configuration
451 is less restrict than create_default_context()'s to increase backward
452 compatibility.
453 """
454 if not isinstance(purpose, _ASN1Object):
455 raise TypeError(purpose)
456
457 context = SSLContext(protocol)
458 # SSLv2 considered harmful.
459 context.options |= OP_NO_SSLv2
Antoine Pitrou95b61642014-10-17 19:28:30 +0200460 # SSLv3 has problematic security and is only required for really old
461 # clients such as IE6 on Windows XP
462 context.options |= OP_NO_SSLv3
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500463
464 if cert_reqs is not None:
465 context.verify_mode = cert_reqs
466 context.check_hostname = check_hostname
467
468 if keyfile and not certfile:
469 raise ValueError("certfile must be specified")
470 if certfile or keyfile:
471 context.load_cert_chain(certfile, keyfile)
472
473 # load CA root certs
474 if cafile or capath or cadata:
475 context.load_verify_locations(cafile, capath, cadata)
476 elif context.verify_mode != CERT_NONE:
477 # no explicit cafile, capath or cadata but the verify mode is
478 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
479 # root CA certificates for the given purpose. This may fail silently.
480 context.load_default_certs(purpose)
481
482 return context
Antoine Pitroud76088d2012-01-03 22:46:48 +0100483
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600484# Used by http.client if no context is explicitly passed.
485_create_default_https_context = create_default_context
486
487
488# Backwards compatibility alias, even though it's not a public name.
489_create_stdlib_context = _create_unverified_context
490
491
Ezio Melottib01f5e62010-01-18 09:10:26 +0000492class SSLSocket(socket):
Bill Janssen426ea0a2007-08-29 22:35:05 +0000493 """This class implements a subtype of socket.socket that wraps
494 the underlying OS socket in an SSL context when necessary, and
495 provides read and write methods over that channel."""
496
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500497 def __init__(self, sock=None, keyfile=None, certfile=None,
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000498 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen934b16d2008-06-28 22:19:33 +0000499 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
500 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500501 family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
502 suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
503 server_hostname=None,
504 _context=None):
505
Benjamin Peterson5f6b89b2014-11-23 11:16:48 -0600506 self._makefile_refs = 0
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500507 if _context:
508 self._context = _context
509 else:
510 if server_side and not certfile:
511 raise ValueError("certfile must be specified for server-side "
512 "operations")
513 if keyfile and not certfile:
514 raise ValueError("certfile must be specified")
515 if certfile and not keyfile:
516 keyfile = certfile
517 self._context = SSLContext(ssl_version)
518 self._context.verify_mode = cert_reqs
519 if ca_certs:
520 self._context.load_verify_locations(ca_certs)
521 if certfile:
522 self._context.load_cert_chain(certfile, keyfile)
523 if npn_protocols:
524 self._context.set_npn_protocols(npn_protocols)
525 if ciphers:
526 self._context.set_ciphers(ciphers)
527 self.keyfile = keyfile
528 self.certfile = certfile
529 self.cert_reqs = cert_reqs
530 self.ssl_version = ssl_version
531 self.ca_certs = ca_certs
532 self.ciphers = ciphers
Antoine Pitrou63cc99d2013-12-28 17:26:33 +0100533 # Can't use sock.type as other flags (such as SOCK_NONBLOCK) get
534 # mixed in.
535 if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
536 raise NotImplementedError("only stream sockets are supported")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000537 socket.__init__(self, _sock=sock._sock)
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000538 # The initializer for socket overrides the methods send(), recv(), etc.
539 # in the instancce, which we don't need -- but we want to provide the
540 # methods defined in SSLSocket.
541 for attr in _delegate_methods:
542 try:
543 delattr(self, attr)
544 except AttributeError:
545 pass
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500546 if server_side and server_hostname:
547 raise ValueError("server_hostname can only be specified "
548 "in client mode")
549 if self._context.check_hostname and not server_hostname:
Benjamin Peterson31aa69e2014-11-23 20:13:31 -0600550 raise ValueError("check_hostname requires server_hostname")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500551 self.server_side = server_side
552 self.server_hostname = server_hostname
Bill Janssen934b16d2008-06-28 22:19:33 +0000553 self.do_handshake_on_connect = do_handshake_on_connect
554 self.suppress_ragged_eofs = suppress_ragged_eofs
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500555
556 # See if we are connected
557 try:
558 self.getpeername()
559 except socket_error as e:
560 if e.errno != errno.ENOTCONN:
561 raise
562 connected = False
563 else:
564 connected = True
565
566 self._closed = False
567 self._sslobj = None
568 self._connected = connected
569 if connected:
570 # create the SSL object
571 try:
572 self._sslobj = self._context._wrap_socket(self._sock, server_side,
573 server_hostname, ssl_sock=self)
574 if do_handshake_on_connect:
575 timeout = self.gettimeout()
576 if timeout == 0.0:
577 # non-blocking
578 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
579 self.do_handshake()
580
581 except (OSError, ValueError):
582 self.close()
583 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000584
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500585 @property
586 def context(self):
587 return self._context
Bill Janssen24bccf22007-08-30 17:07:28 +0000588
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500589 @context.setter
590 def context(self, ctx):
591 self._context = ctx
592 self._sslobj.context = ctx
593
594 def dup(self):
595 raise NotImplemented("Can't dup() %s instances" %
596 self.__class__.__name__)
597
598 def _checkClosed(self, msg=None):
599 # raise an exception here if you wish to check for spurious closes
600 pass
601
602 def _check_connected(self):
603 if not self._connected:
604 # getpeername() will raise ENOTCONN if the socket is really
605 # not connected; note that we can be connected even without
606 # _connected being set, e.g. if connect() first returned
607 # EAGAIN.
608 self.getpeername()
609
610 def read(self, len=0, buffer=None):
Bill Janssen24bccf22007-08-30 17:07:28 +0000611 """Read up to LEN bytes and return them.
612 Return zero-length string on EOF."""
613
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500614 self._checkClosed()
615 if not self._sslobj:
616 raise ValueError("Read on closed or unwrapped SSL socket.")
Bill Janssen934b16d2008-06-28 22:19:33 +0000617 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500618 if buffer is not None:
619 v = self._sslobj.read(len, buffer)
620 else:
621 v = self._sslobj.read(len or 1024)
622 return v
623 except SSLError as x:
Bill Janssen934b16d2008-06-28 22:19:33 +0000624 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500625 if buffer is not None:
626 return 0
627 else:
628 return b''
Bill Janssen934b16d2008-06-28 22:19:33 +0000629 else:
630 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000631
632 def write(self, data):
Bill Janssen24bccf22007-08-30 17:07:28 +0000633 """Write DATA to the underlying SSL channel. Returns
634 number of bytes of DATA actually transmitted."""
635
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500636 self._checkClosed()
637 if not self._sslobj:
638 raise ValueError("Write on closed or unwrapped SSL socket.")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000639 return self._sslobj.write(data)
640
Bill Janssen98d19da2007-09-10 21:51:02 +0000641 def getpeercert(self, binary_form=False):
Bill Janssen24bccf22007-08-30 17:07:28 +0000642 """Returns a formatted version of the data in the
643 certificate provided by the other end of the SSL channel.
644 Return None if no certificate was provided, {} if a
645 certificate was provided, but not validated."""
646
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500647 self._checkClosed()
648 self._check_connected()
Bill Janssen98d19da2007-09-10 21:51:02 +0000649 return self._sslobj.peer_certificate(binary_form)
650
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500651 def selected_npn_protocol(self):
652 self._checkClosed()
653 if not self._sslobj or not _ssl.HAS_NPN:
654 return None
655 else:
656 return self._sslobj.selected_npn_protocol()
Bill Janssen98d19da2007-09-10 21:51:02 +0000657
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -0500658 def selected_alpn_protocol(self):
659 self._checkClosed()
660 if not self._sslobj or not _ssl.HAS_ALPN:
661 return None
662 else:
663 return self._sslobj.selected_alpn_protocol()
664
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500665 def cipher(self):
666 self._checkClosed()
Bill Janssen98d19da2007-09-10 21:51:02 +0000667 if not self._sslobj:
668 return None
669 else:
670 return self._sslobj.cipher()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000671
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500672 def compression(self):
673 self._checkClosed()
674 if not self._sslobj:
675 return None
676 else:
677 return self._sslobj.compression()
678
Ezio Melottib01f5e62010-01-18 09:10:26 +0000679 def send(self, data, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500680 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000681 if self._sslobj:
682 if flags != 0:
683 raise ValueError(
684 "non-zero flags not allowed in calls to send() on %s" %
685 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500686 try:
687 v = self._sslobj.write(data)
688 except SSLError as x:
689 if x.args[0] == SSL_ERROR_WANT_READ:
690 return 0
691 elif x.args[0] == SSL_ERROR_WANT_WRITE:
692 return 0
Bill Janssen934b16d2008-06-28 22:19:33 +0000693 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500694 raise
695 else:
696 return v
Bill Janssen426ea0a2007-08-29 22:35:05 +0000697 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000698 return self._sock.send(data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000699
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000700 def sendto(self, data, flags_or_addr, addr=None):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500701 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000702 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000703 raise ValueError("sendto not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000704 self.__class__)
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000705 elif addr is None:
706 return self._sock.sendto(data, flags_or_addr)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000707 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000708 return self._sock.sendto(data, flags_or_addr, addr)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000709
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500710
Ezio Melottib01f5e62010-01-18 09:10:26 +0000711 def sendall(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 sendall() on %s" %
717 self.__class__)
Bill Janssen934b16d2008-06-28 22:19:33 +0000718 amount = len(data)
719 count = 0
720 while (count < amount):
721 v = self.send(data[count:])
722 count += v
723 return amount
Bill Janssen426ea0a2007-08-29 22:35:05 +0000724 else:
725 return socket.sendall(self, data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000726
Ezio Melottib01f5e62010-01-18 09:10:26 +0000727 def recv(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500728 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000729 if self._sslobj:
730 if flags != 0:
731 raise ValueError(
Antoine Pitrou448da712010-03-21 19:33:38 +0000732 "non-zero flags not allowed in calls to recv() on %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000733 self.__class__)
Antoine Pitrou448da712010-03-21 19:33:38 +0000734 return self.read(buflen)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000735 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000736 return self._sock.recv(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000737
Ezio Melottib01f5e62010-01-18 09:10:26 +0000738 def recv_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500739 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000740 if buffer and (nbytes is None):
741 nbytes = len(buffer)
742 elif nbytes is None:
743 nbytes = 1024
744 if self._sslobj:
745 if flags != 0:
746 raise ValueError(
747 "non-zero flags not allowed in calls to recv_into() on %s" %
748 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500749 return self.read(nbytes, buffer)
Bill Janssen61c001a2008-09-08 16:37:24 +0000750 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000751 return self._sock.recv_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000752
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000753 def recvfrom(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500754 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000755 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000756 raise ValueError("recvfrom not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000757 self.__class__)
758 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000759 return self._sock.recvfrom(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000760
Ezio Melottib01f5e62010-01-18 09:10:26 +0000761 def recvfrom_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500762 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000763 if self._sslobj:
764 raise ValueError("recvfrom_into not allowed on instances of %s" %
765 self.__class__)
766 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000767 return self._sock.recvfrom_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000768
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500769
Ezio Melottib01f5e62010-01-18 09:10:26 +0000770 def pending(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500771 self._checkClosed()
Bill Janssen934b16d2008-06-28 22:19:33 +0000772 if self._sslobj:
773 return self._sslobj.pending()
774 else:
775 return 0
776
Ezio Melottib01f5e62010-01-18 09:10:26 +0000777 def shutdown(self, how):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500778 self._checkClosed()
Bill Janssen296a59d2007-09-16 22:06:00 +0000779 self._sslobj = None
Bill Janssen426ea0a2007-08-29 22:35:05 +0000780 socket.shutdown(self, how)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000781
Ezio Melottib01f5e62010-01-18 09:10:26 +0000782 def close(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000783 if self._makefile_refs < 1:
784 self._sslobj = None
785 socket.close(self)
786 else:
787 self._makefile_refs -= 1
788
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500789 def unwrap(self):
790 if self._sslobj:
791 s = self._sslobj.shutdown()
792 self._sslobj = None
793 return s
794 else:
795 raise ValueError("No SSL wrapper around " + str(self))
Bill Janssen934b16d2008-06-28 22:19:33 +0000796
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500797 def _real_close(self):
798 self._sslobj = None
799 socket._real_close(self)
800
801 def do_handshake(self, block=False):
Bill Janssen934b16d2008-06-28 22:19:33 +0000802 """Perform a TLS/SSL handshake."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500803 self._check_connected()
804 timeout = self.gettimeout()
805 try:
806 if timeout == 0.0 and block:
807 self.settimeout(None)
808 self._sslobj.do_handshake()
809 finally:
810 self.settimeout(timeout)
Bill Janssen934b16d2008-06-28 22:19:33 +0000811
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500812 if self.context.check_hostname:
813 if not self.server_hostname:
814 raise ValueError("check_hostname needs server_hostname "
815 "argument")
816 match_hostname(self.getpeercert(), self.server_hostname)
Bill Janssen934b16d2008-06-28 22:19:33 +0000817
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500818 def _real_connect(self, addr, connect_ex):
819 if self.server_side:
820 raise ValueError("can't connect in server-side mode")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000821 # Here we assume that the socket is client-side, and not
822 # connected at the time of the call. We connect it, then wrap it.
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000823 if self._connected:
Bill Janssen98d19da2007-09-10 21:51:02 +0000824 raise ValueError("attempt to connect already-connected SSLSocket!")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500825 self._sslobj = self.context._wrap_socket(self._sock, False, self.server_hostname, ssl_sock=self)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000826 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500827 if connect_ex:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100828 rc = socket.connect_ex(self, addr)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000829 else:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100830 rc = None
831 socket.connect(self, addr)
832 if not rc:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500833 self._connected = True
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100834 if self.do_handshake_on_connect:
835 self.do_handshake()
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100836 return rc
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500837 except (OSError, ValueError):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100838 self._sslobj = None
839 raise
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000840
841 def connect(self, addr):
842 """Connects to remote ADDR, and then wraps the connection in
843 an SSL channel."""
844 self._real_connect(addr, False)
845
846 def connect_ex(self, addr):
847 """Connects to remote ADDR, and then wraps the connection in
848 an SSL channel."""
849 return self._real_connect(addr, True)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000850
851 def accept(self):
Bill Janssen24bccf22007-08-30 17:07:28 +0000852 """Accepts a new connection from a remote client, and returns
853 a tuple containing that new connection wrapped with a server-side
854 SSL channel, and the address of the remote client."""
855
Bill Janssen426ea0a2007-08-29 22:35:05 +0000856 newsock, addr = socket.accept(self)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500857 newsock = self.context.wrap_socket(newsock,
858 do_handshake_on_connect=self.do_handshake_on_connect,
859 suppress_ragged_eofs=self.suppress_ragged_eofs,
860 server_side=True)
861 return newsock, addr
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000862
Bill Janssen296a59d2007-09-16 22:06:00 +0000863 def makefile(self, mode='r', bufsize=-1):
864
Bill Janssen61c001a2008-09-08 16:37:24 +0000865 """Make and return a file-like object that
866 works with the SSL connection. Just use the code
867 from the socket module."""
Bill Janssen296a59d2007-09-16 22:06:00 +0000868
Bill Janssen934b16d2008-06-28 22:19:33 +0000869 self._makefile_refs += 1
Antoine Pitroub558f172010-04-23 23:25:45 +0000870 # close=True so as to decrement the reference count when done with
871 # the file-like object.
872 return _fileobject(self, mode, bufsize, close=True)
Bill Janssen296a59d2007-09-16 22:06:00 +0000873
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500874 def get_channel_binding(self, cb_type="tls-unique"):
875 """Get channel binding data for current connection. Raise ValueError
876 if the requested `cb_type` is not supported. Return bytes of the data
877 or None if the data is not available (e.g. before the handshake).
878 """
879 if cb_type not in CHANNEL_BINDING_TYPES:
880 raise ValueError("Unsupported channel binding type")
881 if cb_type != "tls-unique":
882 raise NotImplementedError(
883 "{0} channel binding type not implemented"
884 .format(cb_type))
885 if self._sslobj is None:
886 return None
887 return self._sslobj.tls_unique_cb()
Bill Janssen296a59d2007-09-16 22:06:00 +0000888
Alex Gaynore98205d2014-09-04 13:33:22 -0700889 def version(self):
890 """
891 Return a string identifying the protocol version used by the
892 current SSL channel, or None if there is no established channel.
893 """
894 if self._sslobj is None:
895 return None
896 return self._sslobj.version()
897
Bill Janssen296a59d2007-09-16 22:06:00 +0000898
Bill Janssen98d19da2007-09-10 21:51:02 +0000899def wrap_socket(sock, keyfile=None, certfile=None,
900 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen934b16d2008-06-28 22:19:33 +0000901 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
902 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500903 suppress_ragged_eofs=True,
904 ciphers=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000905
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500906 return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000907 server_side=server_side, cert_reqs=cert_reqs,
Bill Janssen934b16d2008-06-28 22:19:33 +0000908 ssl_version=ssl_version, ca_certs=ca_certs,
909 do_handshake_on_connect=do_handshake_on_connect,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000910 suppress_ragged_eofs=suppress_ragged_eofs,
911 ciphers=ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000912
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000913# some utility functions
914
915def cert_time_to_seconds(cert_time):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500916 """Return the time in seconds since the Epoch, given the timestring
917 representing the "notBefore" or "notAfter" date from a certificate
918 in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale).
Bill Janssen24bccf22007-08-30 17:07:28 +0000919
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500920 "notBefore" or "notAfter" dates must use UTC (RFC 5280).
Bill Janssen24bccf22007-08-30 17:07:28 +0000921
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500922 Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
923 UTC should be specified as GMT (see ASN1_TIME_print())
924 """
925 from time import strptime
926 from calendar import timegm
927
928 months = (
929 "Jan","Feb","Mar","Apr","May","Jun",
930 "Jul","Aug","Sep","Oct","Nov","Dec"
931 )
932 time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT
933 try:
934 month_number = months.index(cert_time[:3].title()) + 1
935 except ValueError:
936 raise ValueError('time data %r does not match '
937 'format "%%b%s"' % (cert_time, time_format))
938 else:
939 # found valid month
940 tt = strptime(cert_time[3:], time_format)
941 # return an integer, the previous mktime()-based implementation
942 # returned a float (fractional seconds are always zero here).
943 return timegm((tt[0], month_number) + tt[2:6])
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000944
Bill Janssen296a59d2007-09-16 22:06:00 +0000945PEM_HEADER = "-----BEGIN CERTIFICATE-----"
946PEM_FOOTER = "-----END CERTIFICATE-----"
947
948def DER_cert_to_PEM_cert(der_cert_bytes):
Bill Janssen296a59d2007-09-16 22:06:00 +0000949 """Takes a certificate in binary DER format and returns the
950 PEM version of it as a string."""
951
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500952 f = base64.standard_b64encode(der_cert_bytes).decode('ascii')
953 return (PEM_HEADER + '\n' +
954 textwrap.fill(f, 64) + '\n' +
955 PEM_FOOTER + '\n')
Bill Janssen296a59d2007-09-16 22:06:00 +0000956
957def PEM_cert_to_DER_cert(pem_cert_string):
Bill Janssen296a59d2007-09-16 22:06:00 +0000958 """Takes a certificate in ASCII PEM format and returns the
959 DER-encoded version of it as a byte sequence"""
960
961 if not pem_cert_string.startswith(PEM_HEADER):
962 raise ValueError("Invalid PEM encoding; must start with %s"
963 % PEM_HEADER)
964 if not pem_cert_string.strip().endswith(PEM_FOOTER):
965 raise ValueError("Invalid PEM encoding; must end with %s"
966 % PEM_FOOTER)
967 d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500968 return base64.decodestring(d.encode('ASCII', 'strict'))
Bill Janssen296a59d2007-09-16 22:06:00 +0000969
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500970def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000971 """Retrieve the certificate from the server at the specified address,
972 and return it as a PEM-encoded string.
973 If 'ca_certs' is specified, validate the server cert against it.
974 If 'ssl_version' is specified, use it in the connection attempt."""
975
976 host, port = addr
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500977 if ca_certs is not None:
Bill Janssen296a59d2007-09-16 22:06:00 +0000978 cert_reqs = CERT_REQUIRED
979 else:
980 cert_reqs = CERT_NONE
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500981 context = _create_stdlib_context(ssl_version,
982 cert_reqs=cert_reqs,
983 cafile=ca_certs)
984 with closing(create_connection(addr)) as sock:
985 with closing(context.wrap_socket(sock)) as sslsock:
986 dercert = sslsock.getpeercert(True)
Bill Janssen296a59d2007-09-16 22:06:00 +0000987 return DER_cert_to_PEM_cert(dercert)
988
Ezio Melottib01f5e62010-01-18 09:10:26 +0000989def get_protocol_name(protocol_code):
Victor Stinnerb1241f92011-05-10 01:52:03 +0200990 return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
Bill Janssen296a59d2007-09-16 22:06:00 +0000991
992
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000993# a replacement for the old socket.ssl function
994
Ezio Melottib01f5e62010-01-18 09:10:26 +0000995def sslwrap_simple(sock, keyfile=None, certfile=None):
Bill Janssen24bccf22007-08-30 17:07:28 +0000996 """A replacement for the old socket.ssl function. Designed
997 for compability with Python 2.5 and earlier. Will disappear in
998 Python 3.0."""
Bill Jansseneb257ac2008-09-29 18:56:38 +0000999 if hasattr(sock, "_sock"):
1000 sock = sock._sock
1001
Benjamin Peterson2f334562014-10-01 23:53:01 -04001002 ctx = SSLContext(PROTOCOL_SSLv23)
1003 if keyfile or certfile:
1004 ctx.load_cert_chain(certfile, keyfile)
1005 ssl_sock = ctx._wrap_socket(sock, server_side=False)
Bill Jansseneb257ac2008-09-29 18:56:38 +00001006 try:
1007 sock.getpeername()
Benjamin Peterson941db4d2008-12-31 04:08:55 +00001008 except socket_error:
Bill Jansseneb257ac2008-09-29 18:56:38 +00001009 # no, no connection yet
1010 pass
1011 else:
1012 # yes, do the handshake
1013 ssl_sock.do_handshake()
1014
Bill Janssen934b16d2008-06-28 22:19:33 +00001015 return ssl_sock