blob: d6fed88cfe6d531c352ad7729991f8942cd0d519 [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
Victor Stinner7c906672015-01-06 13:53:37 +0100109from _ssl import RAND_status, RAND_add
110try:
111 from _ssl import RAND_egd
112except ImportError:
113 # LibreSSL does not provide RAND_egd
114 pass
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500115
116def _import_symbols(prefix):
117 for n in dir(_ssl):
118 if n.startswith(prefix):
119 globals()[n] = getattr(_ssl, n)
120
121_import_symbols('OP_')
122_import_symbols('ALERT_DESCRIPTION_')
123_import_symbols('SSL_ERROR_')
124_import_symbols('PROTOCOL_')
125
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
130_PROTOCOL_NAMES = {value: name for name, value in globals().items() if name.startswith('PROTOCOL_')}
131
Victor Stinnerb1241f92011-05-10 01:52:03 +0200132try:
Antoine Pitroud76088d2012-01-03 22:46:48 +0100133 _SSLv2_IF_EXISTS = PROTOCOL_SSLv2
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500134except NameError:
Antoine Pitroud76088d2012-01-03 22:46:48 +0100135 _SSLv2_IF_EXISTS = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000136
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000137from socket import socket, _fileobject, _delegate_methods, error as socket_error
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500138if sys.platform == "win32":
139 from _ssl import enum_certificates, enum_crls
140
141from socket import socket, AF_INET, SOCK_STREAM, create_connection
142from socket import SOL_SOCKET, SO_TYPE
Bill Janssen296a59d2007-09-16 22:06:00 +0000143import base64 # for DER-to-PEM translation
Antoine Pitrou278d6652010-04-26 17:23:33 +0000144import errno
Bill Janssen98d19da2007-09-10 21:51:02 +0000145
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500146if _ssl.HAS_TLS_UNIQUE:
147 CHANNEL_BINDING_TYPES = ['tls-unique']
148else:
149 CHANNEL_BINDING_TYPES = []
150
Antoine Pitroud76088d2012-01-03 22:46:48 +0100151# Disable weak or insecure ciphers by default
152# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500153# Enable a better set of ciphers by default
154# This list has been explicitly chosen to:
155# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
156# * Prefer ECDHE over DHE for better performance
157# * Prefer any AES-GCM over any AES-CBC for better performance and security
158# * Then Use HIGH cipher suites as a fallback
159# * Then Use 3DES as fallback which is secure but slow
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500160# * Disable NULL authentication, NULL encryption, and MD5 MACs for security
161# reasons
162_DEFAULT_CIPHERS = (
163 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
Benjamin Petersona0dd7dc2015-02-19 17:57:08 -0500164 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
165 '!eNULL:!MD5'
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500166)
Antoine Pitroud76088d2012-01-03 22:46:48 +0100167
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500168# Restricted and more secure ciphers for the server side
169# This list has been explicitly chosen to:
170# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
171# * Prefer ECDHE over DHE for better performance
172# * Prefer any AES-GCM over any AES-CBC for better performance and security
173# * Then Use HIGH cipher suites as a fallback
174# * Then Use 3DES as fallback which is secure but slow
175# * Disable NULL authentication, NULL encryption, MD5 MACs, DSS, and RC4 for
176# security reasons
177_RESTRICTED_SERVER_CIPHERS = (
178 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
179 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
180 '!eNULL:!MD5:!DSS:!RC4'
181)
182
183
184class CertificateError(ValueError):
185 pass
186
187
188def _dnsname_match(dn, hostname, max_wildcards=1):
189 """Matching according to RFC 6125, section 6.4.3
190
191 http://tools.ietf.org/html/rfc6125#section-6.4.3
192 """
193 pats = []
194 if not dn:
195 return False
196
197 pieces = dn.split(r'.')
198 leftmost = pieces[0]
199 remainder = pieces[1:]
200
201 wildcards = leftmost.count('*')
202 if wildcards > max_wildcards:
203 # Issue #17980: avoid denials of service by refusing more
204 # than one wildcard per fragment. A survery of established
205 # policy among SSL implementations showed it to be a
206 # reasonable choice.
207 raise CertificateError(
208 "too many wildcards in certificate DNS name: " + repr(dn))
209
210 # speed up common case w/o wildcards
211 if not wildcards:
212 return dn.lower() == hostname.lower()
213
214 # RFC 6125, section 6.4.3, subitem 1.
215 # The client SHOULD NOT attempt to match a presented identifier in which
216 # the wildcard character comprises a label other than the left-most label.
217 if leftmost == '*':
218 # When '*' is a fragment by itself, it matches a non-empty dotless
219 # fragment.
220 pats.append('[^.]+')
221 elif leftmost.startswith('xn--') or hostname.startswith('xn--'):
222 # RFC 6125, section 6.4.3, subitem 3.
223 # The client SHOULD NOT attempt to match a presented identifier
224 # where the wildcard character is embedded within an A-label or
225 # U-label of an internationalized domain name.
226 pats.append(re.escape(leftmost))
227 else:
228 # Otherwise, '*' matches any dotless string, e.g. www*
229 pats.append(re.escape(leftmost).replace(r'\*', '[^.]*'))
230
231 # add the remaining fragments, ignore any wildcards
232 for frag in remainder:
233 pats.append(re.escape(frag))
234
235 pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
236 return pat.match(hostname)
237
238
239def match_hostname(cert, hostname):
240 """Verify that *cert* (in decoded format as returned by
241 SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
242 rules are followed, but IP addresses are not accepted for *hostname*.
243
244 CertificateError is raised on failure. On success, the function
245 returns nothing.
246 """
247 if not cert:
248 raise ValueError("empty or no certificate, match_hostname needs a "
249 "SSL socket or SSL context with either "
250 "CERT_OPTIONAL or CERT_REQUIRED")
251 dnsnames = []
252 san = cert.get('subjectAltName', ())
253 for key, value in san:
254 if key == 'DNS':
255 if _dnsname_match(value, hostname):
256 return
257 dnsnames.append(value)
258 if not dnsnames:
259 # The subject is only checked when there is no dNSName entry
260 # in subjectAltName
261 for sub in cert.get('subject', ()):
262 for key, value in sub:
263 # XXX according to RFC 2818, the most specific Common Name
264 # must be used.
265 if key == 'commonName':
266 if _dnsname_match(value, hostname):
267 return
268 dnsnames.append(value)
269 if len(dnsnames) > 1:
270 raise CertificateError("hostname %r "
271 "doesn't match either of %s"
272 % (hostname, ', '.join(map(repr, dnsnames))))
273 elif len(dnsnames) == 1:
274 raise CertificateError("hostname %r "
275 "doesn't match %r"
276 % (hostname, dnsnames[0]))
277 else:
278 raise CertificateError("no appropriate commonName or "
279 "subjectAltName fields were found")
280
281
282DefaultVerifyPaths = namedtuple("DefaultVerifyPaths",
283 "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env "
284 "openssl_capath")
285
286def get_default_verify_paths():
287 """Return paths to default cafile and capath.
288 """
289 parts = _ssl.get_default_verify_paths()
290
291 # environment vars shadow paths
292 cafile = os.environ.get(parts[0], parts[1])
293 capath = os.environ.get(parts[2], parts[3])
294
295 return DefaultVerifyPaths(cafile if os.path.isfile(cafile) else None,
296 capath if os.path.isdir(capath) else None,
297 *parts)
298
299
300class _ASN1Object(namedtuple("_ASN1Object", "nid shortname longname oid")):
301 """ASN.1 object identifier lookup
302 """
303 __slots__ = ()
304
305 def __new__(cls, oid):
306 return super(_ASN1Object, cls).__new__(cls, *_txt2obj(oid, name=False))
307
308 @classmethod
309 def fromnid(cls, nid):
310 """Create _ASN1Object from OpenSSL numeric ID
311 """
312 return super(_ASN1Object, cls).__new__(cls, *_nid2obj(nid))
313
314 @classmethod
315 def fromname(cls, name):
316 """Create _ASN1Object from short name, long name or OID
317 """
318 return super(_ASN1Object, cls).__new__(cls, *_txt2obj(name, name=True))
319
320
321class Purpose(_ASN1Object):
322 """SSLContext purpose flags with X509v3 Extended Key Usage objects
323 """
324
325Purpose.SERVER_AUTH = Purpose('1.3.6.1.5.5.7.3.1')
326Purpose.CLIENT_AUTH = Purpose('1.3.6.1.5.5.7.3.2')
327
328
329class SSLContext(_SSLContext):
330 """An SSLContext holds various SSL-related configuration options and
331 data, such as certificates and possibly a private key."""
332
333 __slots__ = ('protocol', '__weakref__')
334 _windows_cert_stores = ("CA", "ROOT")
335
336 def __new__(cls, protocol, *args, **kwargs):
337 self = _SSLContext.__new__(cls, protocol)
338 if protocol != _SSLv2_IF_EXISTS:
339 self.set_ciphers(_DEFAULT_CIPHERS)
340 return self
341
342 def __init__(self, protocol):
343 self.protocol = protocol
344
345 def wrap_socket(self, sock, server_side=False,
346 do_handshake_on_connect=True,
347 suppress_ragged_eofs=True,
348 server_hostname=None):
349 return SSLSocket(sock=sock, server_side=server_side,
350 do_handshake_on_connect=do_handshake_on_connect,
351 suppress_ragged_eofs=suppress_ragged_eofs,
352 server_hostname=server_hostname,
353 _context=self)
354
355 def set_npn_protocols(self, npn_protocols):
356 protos = bytearray()
357 for protocol in npn_protocols:
358 b = protocol.encode('ascii')
359 if len(b) == 0 or len(b) > 255:
360 raise SSLError('NPN protocols must be 1 to 255 in length')
361 protos.append(len(b))
362 protos.extend(b)
363
364 self._set_npn_protocols(protos)
365
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -0500366 def set_alpn_protocols(self, alpn_protocols):
367 protos = bytearray()
368 for protocol in alpn_protocols:
369 b = protocol.encode('ascii')
370 if len(b) == 0 or len(b) > 255:
371 raise SSLError('ALPN protocols must be 1 to 255 in length')
372 protos.append(len(b))
373 protos.extend(b)
374
375 self._set_alpn_protocols(protos)
376
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500377 def _load_windows_store_certs(self, storename, purpose):
378 certs = bytearray()
379 for cert, encoding, trust in enum_certificates(storename):
380 # CA certs are never PKCS#7 encoded
381 if encoding == "x509_asn":
382 if trust is True or purpose.oid in trust:
383 certs.extend(cert)
384 self.load_verify_locations(cadata=certs)
385 return certs
386
387 def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
388 if not isinstance(purpose, _ASN1Object):
389 raise TypeError(purpose)
390 if sys.platform == "win32":
391 for storename in self._windows_cert_stores:
392 self._load_windows_store_certs(storename, purpose)
Benjamin Peterson0b30a2b2014-10-03 17:27:05 -0400393 self.set_default_verify_paths()
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500394
395
396def create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None,
397 capath=None, cadata=None):
398 """Create a SSLContext object with default settings.
399
400 NOTE: The protocol and settings may change anytime without prior
401 deprecation. The values represent a fair balance between maximum
402 compatibility and security.
403 """
404 if not isinstance(purpose, _ASN1Object):
405 raise TypeError(purpose)
406
407 context = SSLContext(PROTOCOL_SSLv23)
408
409 # SSLv2 considered harmful.
410 context.options |= OP_NO_SSLv2
411
412 # SSLv3 has problematic security and is only required for really old
413 # clients such as IE6 on Windows XP
414 context.options |= OP_NO_SSLv3
415
416 # disable compression to prevent CRIME attacks (OpenSSL 1.0+)
417 context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0)
418
419 if purpose == Purpose.SERVER_AUTH:
420 # verify certs and host name in client mode
421 context.verify_mode = CERT_REQUIRED
422 context.check_hostname = True
423 elif purpose == Purpose.CLIENT_AUTH:
424 # Prefer the server's ciphers by default so that we get stronger
425 # encryption
426 context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
427
428 # Use single use keys in order to improve forward secrecy
429 context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0)
430 context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0)
431
432 # disallow ciphers with known vulnerabilities
433 context.set_ciphers(_RESTRICTED_SERVER_CIPHERS)
434
435 if cafile or capath or cadata:
436 context.load_verify_locations(cafile, capath, cadata)
437 elif context.verify_mode != CERT_NONE:
438 # no explicit cafile, capath or cadata but the verify mode is
439 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
440 # root CA certificates for the given purpose. This may fail silently.
441 context.load_default_certs(purpose)
442 return context
443
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600444def _create_unverified_context(protocol=PROTOCOL_SSLv23, cert_reqs=None,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500445 check_hostname=False, purpose=Purpose.SERVER_AUTH,
446 certfile=None, keyfile=None,
447 cafile=None, capath=None, cadata=None):
448 """Create a SSLContext object for Python stdlib modules
449
450 All Python stdlib modules shall use this function to create SSLContext
451 objects in order to keep common settings in one place. The configuration
452 is less restrict than create_default_context()'s to increase backward
453 compatibility.
454 """
455 if not isinstance(purpose, _ASN1Object):
456 raise TypeError(purpose)
457
458 context = SSLContext(protocol)
459 # SSLv2 considered harmful.
460 context.options |= OP_NO_SSLv2
Antoine Pitrou95b61642014-10-17 19:28:30 +0200461 # SSLv3 has problematic security and is only required for really old
462 # clients such as IE6 on Windows XP
463 context.options |= OP_NO_SSLv3
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500464
465 if cert_reqs is not None:
466 context.verify_mode = cert_reqs
467 context.check_hostname = check_hostname
468
469 if keyfile and not certfile:
470 raise ValueError("certfile must be specified")
471 if certfile or keyfile:
472 context.load_cert_chain(certfile, keyfile)
473
474 # load CA root certs
475 if cafile or capath or cadata:
476 context.load_verify_locations(cafile, capath, cadata)
477 elif context.verify_mode != CERT_NONE:
478 # no explicit cafile, capath or cadata but the verify mode is
479 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
480 # root CA certificates for the given purpose. This may fail silently.
481 context.load_default_certs(purpose)
482
483 return context
Antoine Pitroud76088d2012-01-03 22:46:48 +0100484
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600485# Used by http.client if no context is explicitly passed.
486_create_default_https_context = create_default_context
487
488
489# Backwards compatibility alias, even though it's not a public name.
490_create_stdlib_context = _create_unverified_context
491
492
Ezio Melottib01f5e62010-01-18 09:10:26 +0000493class SSLSocket(socket):
Bill Janssen426ea0a2007-08-29 22:35:05 +0000494 """This class implements a subtype of socket.socket that wraps
495 the underlying OS socket in an SSL context when necessary, and
496 provides read and write methods over that channel."""
497
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500498 def __init__(self, sock=None, keyfile=None, certfile=None,
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000499 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen934b16d2008-06-28 22:19:33 +0000500 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
501 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500502 family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
503 suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
504 server_hostname=None,
505 _context=None):
506
Benjamin Peterson5f6b89b2014-11-23 11:16:48 -0600507 self._makefile_refs = 0
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500508 if _context:
509 self._context = _context
510 else:
511 if server_side and not certfile:
512 raise ValueError("certfile must be specified for server-side "
513 "operations")
514 if keyfile and not certfile:
515 raise ValueError("certfile must be specified")
516 if certfile and not keyfile:
517 keyfile = certfile
518 self._context = SSLContext(ssl_version)
519 self._context.verify_mode = cert_reqs
520 if ca_certs:
521 self._context.load_verify_locations(ca_certs)
522 if certfile:
523 self._context.load_cert_chain(certfile, keyfile)
524 if npn_protocols:
525 self._context.set_npn_protocols(npn_protocols)
526 if ciphers:
527 self._context.set_ciphers(ciphers)
528 self.keyfile = keyfile
529 self.certfile = certfile
530 self.cert_reqs = cert_reqs
531 self.ssl_version = ssl_version
532 self.ca_certs = ca_certs
533 self.ciphers = ciphers
Antoine Pitrou63cc99d2013-12-28 17:26:33 +0100534 # Can't use sock.type as other flags (such as SOCK_NONBLOCK) get
535 # mixed in.
536 if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
537 raise NotImplementedError("only stream sockets are supported")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000538 socket.__init__(self, _sock=sock._sock)
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000539 # The initializer for socket overrides the methods send(), recv(), etc.
540 # in the instancce, which we don't need -- but we want to provide the
541 # methods defined in SSLSocket.
542 for attr in _delegate_methods:
543 try:
544 delattr(self, attr)
545 except AttributeError:
546 pass
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500547 if server_side and server_hostname:
548 raise ValueError("server_hostname can only be specified "
549 "in client mode")
550 if self._context.check_hostname and not server_hostname:
Benjamin Peterson31aa69e2014-11-23 20:13:31 -0600551 raise ValueError("check_hostname requires server_hostname")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500552 self.server_side = server_side
553 self.server_hostname = server_hostname
Bill Janssen934b16d2008-06-28 22:19:33 +0000554 self.do_handshake_on_connect = do_handshake_on_connect
555 self.suppress_ragged_eofs = suppress_ragged_eofs
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500556
557 # See if we are connected
558 try:
559 self.getpeername()
560 except socket_error as e:
561 if e.errno != errno.ENOTCONN:
562 raise
563 connected = False
564 else:
565 connected = True
566
567 self._closed = False
568 self._sslobj = None
569 self._connected = connected
570 if connected:
571 # create the SSL object
572 try:
573 self._sslobj = self._context._wrap_socket(self._sock, server_side,
574 server_hostname, ssl_sock=self)
575 if do_handshake_on_connect:
576 timeout = self.gettimeout()
577 if timeout == 0.0:
578 # non-blocking
579 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
580 self.do_handshake()
581
582 except (OSError, ValueError):
583 self.close()
584 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000585
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500586 @property
587 def context(self):
588 return self._context
Bill Janssen24bccf22007-08-30 17:07:28 +0000589
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500590 @context.setter
591 def context(self, ctx):
592 self._context = ctx
593 self._sslobj.context = ctx
594
595 def dup(self):
596 raise NotImplemented("Can't dup() %s instances" %
597 self.__class__.__name__)
598
599 def _checkClosed(self, msg=None):
600 # raise an exception here if you wish to check for spurious closes
601 pass
602
603 def _check_connected(self):
604 if not self._connected:
605 # getpeername() will raise ENOTCONN if the socket is really
606 # not connected; note that we can be connected even without
607 # _connected being set, e.g. if connect() first returned
608 # EAGAIN.
609 self.getpeername()
610
611 def read(self, len=0, buffer=None):
Bill Janssen24bccf22007-08-30 17:07:28 +0000612 """Read up to LEN bytes and return them.
613 Return zero-length string on EOF."""
614
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500615 self._checkClosed()
616 if not self._sslobj:
617 raise ValueError("Read on closed or unwrapped SSL socket.")
Bill Janssen934b16d2008-06-28 22:19:33 +0000618 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500619 if buffer is not None:
620 v = self._sslobj.read(len, buffer)
621 else:
622 v = self._sslobj.read(len or 1024)
623 return v
624 except SSLError as x:
Bill Janssen934b16d2008-06-28 22:19:33 +0000625 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500626 if buffer is not None:
627 return 0
628 else:
629 return b''
Bill Janssen934b16d2008-06-28 22:19:33 +0000630 else:
631 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000632
633 def write(self, data):
Bill Janssen24bccf22007-08-30 17:07:28 +0000634 """Write DATA to the underlying SSL channel. Returns
635 number of bytes of DATA actually transmitted."""
636
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500637 self._checkClosed()
638 if not self._sslobj:
639 raise ValueError("Write on closed or unwrapped SSL socket.")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000640 return self._sslobj.write(data)
641
Bill Janssen98d19da2007-09-10 21:51:02 +0000642 def getpeercert(self, binary_form=False):
Bill Janssen24bccf22007-08-30 17:07:28 +0000643 """Returns a formatted version of the data in the
644 certificate provided by the other end of the SSL channel.
645 Return None if no certificate was provided, {} if a
646 certificate was provided, but not validated."""
647
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500648 self._checkClosed()
649 self._check_connected()
Bill Janssen98d19da2007-09-10 21:51:02 +0000650 return self._sslobj.peer_certificate(binary_form)
651
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500652 def selected_npn_protocol(self):
653 self._checkClosed()
654 if not self._sslobj or not _ssl.HAS_NPN:
655 return None
656 else:
657 return self._sslobj.selected_npn_protocol()
Bill Janssen98d19da2007-09-10 21:51:02 +0000658
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -0500659 def selected_alpn_protocol(self):
660 self._checkClosed()
661 if not self._sslobj or not _ssl.HAS_ALPN:
662 return None
663 else:
664 return self._sslobj.selected_alpn_protocol()
665
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500666 def cipher(self):
667 self._checkClosed()
Bill Janssen98d19da2007-09-10 21:51:02 +0000668 if not self._sslobj:
669 return None
670 else:
671 return self._sslobj.cipher()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000672
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500673 def compression(self):
674 self._checkClosed()
675 if not self._sslobj:
676 return None
677 else:
678 return self._sslobj.compression()
679
Ezio Melottib01f5e62010-01-18 09:10:26 +0000680 def send(self, data, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500681 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000682 if self._sslobj:
683 if flags != 0:
684 raise ValueError(
685 "non-zero flags not allowed in calls to send() on %s" %
686 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500687 try:
688 v = self._sslobj.write(data)
689 except SSLError as x:
690 if x.args[0] == SSL_ERROR_WANT_READ:
691 return 0
692 elif x.args[0] == SSL_ERROR_WANT_WRITE:
693 return 0
Bill Janssen934b16d2008-06-28 22:19:33 +0000694 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500695 raise
696 else:
697 return v
Bill Janssen426ea0a2007-08-29 22:35:05 +0000698 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000699 return self._sock.send(data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000700
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000701 def sendto(self, data, flags_or_addr, addr=None):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500702 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000703 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000704 raise ValueError("sendto not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000705 self.__class__)
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000706 elif addr is None:
707 return self._sock.sendto(data, flags_or_addr)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000708 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000709 return self._sock.sendto(data, flags_or_addr, addr)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000710
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500711
Ezio Melottib01f5e62010-01-18 09:10:26 +0000712 def sendall(self, data, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500713 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000714 if self._sslobj:
715 if flags != 0:
716 raise ValueError(
717 "non-zero flags not allowed in calls to sendall() on %s" %
718 self.__class__)
Bill Janssen934b16d2008-06-28 22:19:33 +0000719 amount = len(data)
720 count = 0
721 while (count < amount):
722 v = self.send(data[count:])
723 count += v
724 return amount
Bill Janssen426ea0a2007-08-29 22:35:05 +0000725 else:
726 return socket.sendall(self, data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000727
Ezio Melottib01f5e62010-01-18 09:10:26 +0000728 def recv(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500729 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000730 if self._sslobj:
731 if flags != 0:
732 raise ValueError(
Antoine Pitrou448da712010-03-21 19:33:38 +0000733 "non-zero flags not allowed in calls to recv() on %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000734 self.__class__)
Antoine Pitrou448da712010-03-21 19:33:38 +0000735 return self.read(buflen)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000736 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000737 return self._sock.recv(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000738
Ezio Melottib01f5e62010-01-18 09:10:26 +0000739 def recv_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500740 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000741 if buffer and (nbytes is None):
742 nbytes = len(buffer)
743 elif nbytes is None:
744 nbytes = 1024
745 if self._sslobj:
746 if flags != 0:
747 raise ValueError(
748 "non-zero flags not allowed in calls to recv_into() on %s" %
749 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500750 return self.read(nbytes, buffer)
Bill Janssen61c001a2008-09-08 16:37:24 +0000751 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000752 return self._sock.recv_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000753
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000754 def recvfrom(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500755 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000756 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000757 raise ValueError("recvfrom not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000758 self.__class__)
759 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000760 return self._sock.recvfrom(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000761
Ezio Melottib01f5e62010-01-18 09:10:26 +0000762 def recvfrom_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500763 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000764 if self._sslobj:
765 raise ValueError("recvfrom_into not allowed on instances of %s" %
766 self.__class__)
767 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000768 return self._sock.recvfrom_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000769
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500770
Ezio Melottib01f5e62010-01-18 09:10:26 +0000771 def pending(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500772 self._checkClosed()
Bill Janssen934b16d2008-06-28 22:19:33 +0000773 if self._sslobj:
774 return self._sslobj.pending()
775 else:
776 return 0
777
Ezio Melottib01f5e62010-01-18 09:10:26 +0000778 def shutdown(self, how):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500779 self._checkClosed()
Bill Janssen296a59d2007-09-16 22:06:00 +0000780 self._sslobj = None
Bill Janssen426ea0a2007-08-29 22:35:05 +0000781 socket.shutdown(self, how)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000782
Ezio Melottib01f5e62010-01-18 09:10:26 +0000783 def close(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000784 if self._makefile_refs < 1:
785 self._sslobj = None
786 socket.close(self)
787 else:
788 self._makefile_refs -= 1
789
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500790 def unwrap(self):
791 if self._sslobj:
792 s = self._sslobj.shutdown()
793 self._sslobj = None
794 return s
795 else:
796 raise ValueError("No SSL wrapper around " + str(self))
Bill Janssen934b16d2008-06-28 22:19:33 +0000797
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500798 def _real_close(self):
799 self._sslobj = None
800 socket._real_close(self)
801
802 def do_handshake(self, block=False):
Bill Janssen934b16d2008-06-28 22:19:33 +0000803 """Perform a TLS/SSL handshake."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500804 self._check_connected()
805 timeout = self.gettimeout()
806 try:
807 if timeout == 0.0 and block:
808 self.settimeout(None)
809 self._sslobj.do_handshake()
810 finally:
811 self.settimeout(timeout)
Bill Janssen934b16d2008-06-28 22:19:33 +0000812
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500813 if self.context.check_hostname:
814 if not self.server_hostname:
815 raise ValueError("check_hostname needs server_hostname "
816 "argument")
817 match_hostname(self.getpeercert(), self.server_hostname)
Bill Janssen934b16d2008-06-28 22:19:33 +0000818
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500819 def _real_connect(self, addr, connect_ex):
820 if self.server_side:
821 raise ValueError("can't connect in server-side mode")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000822 # Here we assume that the socket is client-side, and not
823 # connected at the time of the call. We connect it, then wrap it.
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000824 if self._connected:
Bill Janssen98d19da2007-09-10 21:51:02 +0000825 raise ValueError("attempt to connect already-connected SSLSocket!")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500826 self._sslobj = self.context._wrap_socket(self._sock, False, self.server_hostname, ssl_sock=self)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000827 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500828 if connect_ex:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100829 rc = socket.connect_ex(self, addr)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000830 else:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100831 rc = None
832 socket.connect(self, addr)
833 if not rc:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500834 self._connected = True
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100835 if self.do_handshake_on_connect:
836 self.do_handshake()
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100837 return rc
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500838 except (OSError, ValueError):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100839 self._sslobj = None
840 raise
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000841
842 def connect(self, addr):
843 """Connects to remote ADDR, and then wraps the connection in
844 an SSL channel."""
845 self._real_connect(addr, False)
846
847 def connect_ex(self, addr):
848 """Connects to remote ADDR, and then wraps the connection in
849 an SSL channel."""
850 return self._real_connect(addr, True)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000851
852 def accept(self):
Bill Janssen24bccf22007-08-30 17:07:28 +0000853 """Accepts a new connection from a remote client, and returns
854 a tuple containing that new connection wrapped with a server-side
855 SSL channel, and the address of the remote client."""
856
Bill Janssen426ea0a2007-08-29 22:35:05 +0000857 newsock, addr = socket.accept(self)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500858 newsock = self.context.wrap_socket(newsock,
859 do_handshake_on_connect=self.do_handshake_on_connect,
860 suppress_ragged_eofs=self.suppress_ragged_eofs,
861 server_side=True)
862 return newsock, addr
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000863
Bill Janssen296a59d2007-09-16 22:06:00 +0000864 def makefile(self, mode='r', bufsize=-1):
865
Bill Janssen61c001a2008-09-08 16:37:24 +0000866 """Make and return a file-like object that
867 works with the SSL connection. Just use the code
868 from the socket module."""
Bill Janssen296a59d2007-09-16 22:06:00 +0000869
Bill Janssen934b16d2008-06-28 22:19:33 +0000870 self._makefile_refs += 1
Antoine Pitroub558f172010-04-23 23:25:45 +0000871 # close=True so as to decrement the reference count when done with
872 # the file-like object.
873 return _fileobject(self, mode, bufsize, close=True)
Bill Janssen296a59d2007-09-16 22:06:00 +0000874
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500875 def get_channel_binding(self, cb_type="tls-unique"):
876 """Get channel binding data for current connection. Raise ValueError
877 if the requested `cb_type` is not supported. Return bytes of the data
878 or None if the data is not available (e.g. before the handshake).
879 """
880 if cb_type not in CHANNEL_BINDING_TYPES:
881 raise ValueError("Unsupported channel binding type")
882 if cb_type != "tls-unique":
883 raise NotImplementedError(
884 "{0} channel binding type not implemented"
885 .format(cb_type))
886 if self._sslobj is None:
887 return None
888 return self._sslobj.tls_unique_cb()
Bill Janssen296a59d2007-09-16 22:06:00 +0000889
Alex Gaynore98205d2014-09-04 13:33:22 -0700890 def version(self):
891 """
892 Return a string identifying the protocol version used by the
893 current SSL channel, or None if there is no established channel.
894 """
895 if self._sslobj is None:
896 return None
897 return self._sslobj.version()
898
Bill Janssen296a59d2007-09-16 22:06:00 +0000899
Bill Janssen98d19da2007-09-10 21:51:02 +0000900def wrap_socket(sock, keyfile=None, certfile=None,
901 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen934b16d2008-06-28 22:19:33 +0000902 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
903 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500904 suppress_ragged_eofs=True,
905 ciphers=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000906
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500907 return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000908 server_side=server_side, cert_reqs=cert_reqs,
Bill Janssen934b16d2008-06-28 22:19:33 +0000909 ssl_version=ssl_version, ca_certs=ca_certs,
910 do_handshake_on_connect=do_handshake_on_connect,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000911 suppress_ragged_eofs=suppress_ragged_eofs,
912 ciphers=ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000913
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000914# some utility functions
915
916def cert_time_to_seconds(cert_time):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500917 """Return the time in seconds since the Epoch, given the timestring
918 representing the "notBefore" or "notAfter" date from a certificate
919 in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale).
Bill Janssen24bccf22007-08-30 17:07:28 +0000920
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500921 "notBefore" or "notAfter" dates must use UTC (RFC 5280).
Bill Janssen24bccf22007-08-30 17:07:28 +0000922
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500923 Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
924 UTC should be specified as GMT (see ASN1_TIME_print())
925 """
926 from time import strptime
927 from calendar import timegm
928
929 months = (
930 "Jan","Feb","Mar","Apr","May","Jun",
931 "Jul","Aug","Sep","Oct","Nov","Dec"
932 )
933 time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT
934 try:
935 month_number = months.index(cert_time[:3].title()) + 1
936 except ValueError:
937 raise ValueError('time data %r does not match '
938 'format "%%b%s"' % (cert_time, time_format))
939 else:
940 # found valid month
941 tt = strptime(cert_time[3:], time_format)
942 # return an integer, the previous mktime()-based implementation
943 # returned a float (fractional seconds are always zero here).
944 return timegm((tt[0], month_number) + tt[2:6])
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000945
Bill Janssen296a59d2007-09-16 22:06:00 +0000946PEM_HEADER = "-----BEGIN CERTIFICATE-----"
947PEM_FOOTER = "-----END CERTIFICATE-----"
948
949def DER_cert_to_PEM_cert(der_cert_bytes):
Bill Janssen296a59d2007-09-16 22:06:00 +0000950 """Takes a certificate in binary DER format and returns the
951 PEM version of it as a string."""
952
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500953 f = base64.standard_b64encode(der_cert_bytes).decode('ascii')
954 return (PEM_HEADER + '\n' +
955 textwrap.fill(f, 64) + '\n' +
956 PEM_FOOTER + '\n')
Bill Janssen296a59d2007-09-16 22:06:00 +0000957
958def PEM_cert_to_DER_cert(pem_cert_string):
Bill Janssen296a59d2007-09-16 22:06:00 +0000959 """Takes a certificate in ASCII PEM format and returns the
960 DER-encoded version of it as a byte sequence"""
961
962 if not pem_cert_string.startswith(PEM_HEADER):
963 raise ValueError("Invalid PEM encoding; must start with %s"
964 % PEM_HEADER)
965 if not pem_cert_string.strip().endswith(PEM_FOOTER):
966 raise ValueError("Invalid PEM encoding; must end with %s"
967 % PEM_FOOTER)
968 d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500969 return base64.decodestring(d.encode('ASCII', 'strict'))
Bill Janssen296a59d2007-09-16 22:06:00 +0000970
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500971def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000972 """Retrieve the certificate from the server at the specified address,
973 and return it as a PEM-encoded string.
974 If 'ca_certs' is specified, validate the server cert against it.
975 If 'ssl_version' is specified, use it in the connection attempt."""
976
977 host, port = addr
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500978 if ca_certs is not None:
Bill Janssen296a59d2007-09-16 22:06:00 +0000979 cert_reqs = CERT_REQUIRED
980 else:
981 cert_reqs = CERT_NONE
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500982 context = _create_stdlib_context(ssl_version,
983 cert_reqs=cert_reqs,
984 cafile=ca_certs)
985 with closing(create_connection(addr)) as sock:
986 with closing(context.wrap_socket(sock)) as sslsock:
987 dercert = sslsock.getpeercert(True)
Bill Janssen296a59d2007-09-16 22:06:00 +0000988 return DER_cert_to_PEM_cert(dercert)
989
Ezio Melottib01f5e62010-01-18 09:10:26 +0000990def get_protocol_name(protocol_code):
Victor Stinnerb1241f92011-05-10 01:52:03 +0200991 return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
Bill Janssen296a59d2007-09-16 22:06:00 +0000992
993
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000994# a replacement for the old socket.ssl function
995
Ezio Melottib01f5e62010-01-18 09:10:26 +0000996def sslwrap_simple(sock, keyfile=None, certfile=None):
Bill Janssen24bccf22007-08-30 17:07:28 +0000997 """A replacement for the old socket.ssl function. Designed
998 for compability with Python 2.5 and earlier. Will disappear in
999 Python 3.0."""
Bill Jansseneb257ac2008-09-29 18:56:38 +00001000 if hasattr(sock, "_sock"):
1001 sock = sock._sock
1002
Benjamin Peterson2f334562014-10-01 23:53:01 -04001003 ctx = SSLContext(PROTOCOL_SSLv23)
1004 if keyfile or certfile:
1005 ctx.load_cert_chain(certfile, keyfile)
1006 ssl_sock = ctx._wrap_socket(sock, server_side=False)
Bill Jansseneb257ac2008-09-29 18:56:38 +00001007 try:
1008 sock.getpeername()
Benjamin Peterson941db4d2008-12-31 04:08:55 +00001009 except socket_error:
Bill Jansseneb257ac2008-09-29 18:56:38 +00001010 # no, no connection yet
1011 pass
1012 else:
1013 # yes, do the handshake
1014 ssl_sock.do_handshake()
1015
Bill Janssen934b16d2008-06-28 22:19:33 +00001016 return ssl_sock