blob: 60703808793345f08ad3f4b71b61a47bba837ce4 [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
Steve Dower90c9b402016-05-26 12:17:21 -0700144import warnings
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()
Steve Dower90c9b402016-05-26 12:17:21 -0700379 try:
380 for cert, encoding, trust in enum_certificates(storename):
381 # CA certs are never PKCS#7 encoded
382 if encoding == "x509_asn":
383 if trust is True or purpose.oid in trust:
384 certs.extend(cert)
385 except OSError:
386 warnings.warn("unable to enumerate Windows certificate store")
Steve Dower9cb20742016-03-17 15:02:19 -0700387 if certs:
388 self.load_verify_locations(cadata=certs)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500389 return certs
390
391 def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
392 if not isinstance(purpose, _ASN1Object):
393 raise TypeError(purpose)
394 if sys.platform == "win32":
395 for storename in self._windows_cert_stores:
396 self._load_windows_store_certs(storename, purpose)
Benjamin Peterson0b30a2b2014-10-03 17:27:05 -0400397 self.set_default_verify_paths()
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500398
399
400def create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None,
401 capath=None, cadata=None):
402 """Create a SSLContext object with default settings.
403
404 NOTE: The protocol and settings may change anytime without prior
405 deprecation. The values represent a fair balance between maximum
406 compatibility and security.
407 """
408 if not isinstance(purpose, _ASN1Object):
409 raise TypeError(purpose)
410
411 context = SSLContext(PROTOCOL_SSLv23)
412
413 # SSLv2 considered harmful.
414 context.options |= OP_NO_SSLv2
415
416 # SSLv3 has problematic security and is only required for really old
417 # clients such as IE6 on Windows XP
418 context.options |= OP_NO_SSLv3
419
420 # disable compression to prevent CRIME attacks (OpenSSL 1.0+)
421 context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0)
422
423 if purpose == Purpose.SERVER_AUTH:
424 # verify certs and host name in client mode
425 context.verify_mode = CERT_REQUIRED
426 context.check_hostname = True
427 elif purpose == Purpose.CLIENT_AUTH:
428 # Prefer the server's ciphers by default so that we get stronger
429 # encryption
430 context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
431
432 # Use single use keys in order to improve forward secrecy
433 context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0)
434 context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0)
435
436 # disallow ciphers with known vulnerabilities
437 context.set_ciphers(_RESTRICTED_SERVER_CIPHERS)
438
439 if cafile or capath or cadata:
440 context.load_verify_locations(cafile, capath, cadata)
441 elif context.verify_mode != CERT_NONE:
442 # no explicit cafile, capath or cadata but the verify mode is
443 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
444 # root CA certificates for the given purpose. This may fail silently.
445 context.load_default_certs(purpose)
446 return context
447
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600448def _create_unverified_context(protocol=PROTOCOL_SSLv23, cert_reqs=None,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500449 check_hostname=False, purpose=Purpose.SERVER_AUTH,
450 certfile=None, keyfile=None,
451 cafile=None, capath=None, cadata=None):
452 """Create a SSLContext object for Python stdlib modules
453
454 All Python stdlib modules shall use this function to create SSLContext
455 objects in order to keep common settings in one place. The configuration
456 is less restrict than create_default_context()'s to increase backward
457 compatibility.
458 """
459 if not isinstance(purpose, _ASN1Object):
460 raise TypeError(purpose)
461
462 context = SSLContext(protocol)
463 # SSLv2 considered harmful.
464 context.options |= OP_NO_SSLv2
Antoine Pitrou95b61642014-10-17 19:28:30 +0200465 # SSLv3 has problematic security and is only required for really old
466 # clients such as IE6 on Windows XP
467 context.options |= OP_NO_SSLv3
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500468
469 if cert_reqs is not None:
470 context.verify_mode = cert_reqs
471 context.check_hostname = check_hostname
472
473 if keyfile and not certfile:
474 raise ValueError("certfile must be specified")
475 if certfile or keyfile:
476 context.load_cert_chain(certfile, keyfile)
477
478 # load CA root certs
479 if cafile or capath or cadata:
480 context.load_verify_locations(cafile, capath, cadata)
481 elif context.verify_mode != CERT_NONE:
482 # no explicit cafile, capath or cadata but the verify mode is
483 # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
484 # root CA certificates for the given purpose. This may fail silently.
485 context.load_default_certs(purpose)
486
487 return context
Antoine Pitroud76088d2012-01-03 22:46:48 +0100488
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600489# Backwards compatibility alias, even though it's not a public name.
490_create_stdlib_context = _create_unverified_context
491
Nick Coghlandbcd4572016-03-20 22:39:15 +1000492# PEP 493: Verify HTTPS by default, but allow envvar to override that
493_https_verify_envvar = 'PYTHONHTTPSVERIFY'
494
495def _get_https_context_factory():
496 if not sys.flags.ignore_environment:
497 config_setting = os.environ.get(_https_verify_envvar)
498 if config_setting == '0':
499 return _create_unverified_context
500 return create_default_context
501
502_create_default_https_context = _get_https_context_factory()
503
504# PEP 493: "private" API to configure HTTPS defaults without monkeypatching
505def _https_verify_certificates(enable=True):
506 """Verify server HTTPS certificates by default?"""
507 global _create_default_https_context
508 if enable:
509 _create_default_https_context = create_default_context
510 else:
511 _create_default_https_context = _create_unverified_context
512
Benjamin Petersone3e7d402014-11-23 21:02:02 -0600513
Ezio Melottib01f5e62010-01-18 09:10:26 +0000514class SSLSocket(socket):
Bill Janssen426ea0a2007-08-29 22:35:05 +0000515 """This class implements a subtype of socket.socket that wraps
516 the underlying OS socket in an SSL context when necessary, and
517 provides read and write methods over that channel."""
518
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500519 def __init__(self, sock=None, keyfile=None, certfile=None,
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000520 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen934b16d2008-06-28 22:19:33 +0000521 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
522 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500523 family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
524 suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
525 server_hostname=None,
526 _context=None):
527
Benjamin Peterson5f6b89b2014-11-23 11:16:48 -0600528 self._makefile_refs = 0
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500529 if _context:
530 self._context = _context
531 else:
532 if server_side and not certfile:
533 raise ValueError("certfile must be specified for server-side "
534 "operations")
535 if keyfile and not certfile:
536 raise ValueError("certfile must be specified")
537 if certfile and not keyfile:
538 keyfile = certfile
539 self._context = SSLContext(ssl_version)
540 self._context.verify_mode = cert_reqs
541 if ca_certs:
542 self._context.load_verify_locations(ca_certs)
543 if certfile:
544 self._context.load_cert_chain(certfile, keyfile)
545 if npn_protocols:
546 self._context.set_npn_protocols(npn_protocols)
547 if ciphers:
548 self._context.set_ciphers(ciphers)
549 self.keyfile = keyfile
550 self.certfile = certfile
551 self.cert_reqs = cert_reqs
552 self.ssl_version = ssl_version
553 self.ca_certs = ca_certs
554 self.ciphers = ciphers
Antoine Pitrou63cc99d2013-12-28 17:26:33 +0100555 # Can't use sock.type as other flags (such as SOCK_NONBLOCK) get
556 # mixed in.
557 if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM:
558 raise NotImplementedError("only stream sockets are supported")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000559 socket.__init__(self, _sock=sock._sock)
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000560 # The initializer for socket overrides the methods send(), recv(), etc.
561 # in the instancce, which we don't need -- but we want to provide the
562 # methods defined in SSLSocket.
563 for attr in _delegate_methods:
564 try:
565 delattr(self, attr)
566 except AttributeError:
567 pass
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500568 if server_side and server_hostname:
569 raise ValueError("server_hostname can only be specified "
570 "in client mode")
571 if self._context.check_hostname and not server_hostname:
Benjamin Peterson31aa69e2014-11-23 20:13:31 -0600572 raise ValueError("check_hostname requires server_hostname")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500573 self.server_side = server_side
574 self.server_hostname = server_hostname
Bill Janssen934b16d2008-06-28 22:19:33 +0000575 self.do_handshake_on_connect = do_handshake_on_connect
576 self.suppress_ragged_eofs = suppress_ragged_eofs
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500577
578 # See if we are connected
579 try:
580 self.getpeername()
581 except socket_error as e:
582 if e.errno != errno.ENOTCONN:
583 raise
584 connected = False
585 else:
586 connected = True
587
588 self._closed = False
589 self._sslobj = None
590 self._connected = connected
591 if connected:
592 # create the SSL object
593 try:
594 self._sslobj = self._context._wrap_socket(self._sock, server_side,
595 server_hostname, ssl_sock=self)
596 if do_handshake_on_connect:
597 timeout = self.gettimeout()
598 if timeout == 0.0:
599 # non-blocking
600 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
601 self.do_handshake()
602
603 except (OSError, ValueError):
604 self.close()
605 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000606
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500607 @property
608 def context(self):
609 return self._context
Bill Janssen24bccf22007-08-30 17:07:28 +0000610
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500611 @context.setter
612 def context(self, ctx):
613 self._context = ctx
614 self._sslobj.context = ctx
615
616 def dup(self):
617 raise NotImplemented("Can't dup() %s instances" %
618 self.__class__.__name__)
619
620 def _checkClosed(self, msg=None):
621 # raise an exception here if you wish to check for spurious closes
622 pass
623
624 def _check_connected(self):
625 if not self._connected:
626 # getpeername() will raise ENOTCONN if the socket is really
627 # not connected; note that we can be connected even without
628 # _connected being set, e.g. if connect() first returned
629 # EAGAIN.
630 self.getpeername()
631
Martin Panterd524b702016-03-28 00:22:09 +0000632 def read(self, len=1024, buffer=None):
Bill Janssen24bccf22007-08-30 17:07:28 +0000633 """Read up to LEN bytes and return them.
634 Return zero-length string on EOF."""
635
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500636 self._checkClosed()
637 if not self._sslobj:
638 raise ValueError("Read on closed or unwrapped SSL socket.")
Bill Janssen934b16d2008-06-28 22:19:33 +0000639 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500640 if buffer is not None:
641 v = self._sslobj.read(len, buffer)
642 else:
Martin Panterd524b702016-03-28 00:22:09 +0000643 v = self._sslobj.read(len)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500644 return v
645 except SSLError as x:
Bill Janssen934b16d2008-06-28 22:19:33 +0000646 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500647 if buffer is not None:
648 return 0
649 else:
650 return b''
Bill Janssen934b16d2008-06-28 22:19:33 +0000651 else:
652 raise
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000653
654 def write(self, data):
Bill Janssen24bccf22007-08-30 17:07:28 +0000655 """Write DATA to the underlying SSL channel. Returns
656 number of bytes of DATA actually transmitted."""
657
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500658 self._checkClosed()
659 if not self._sslobj:
660 raise ValueError("Write on closed or unwrapped SSL socket.")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000661 return self._sslobj.write(data)
662
Bill Janssen98d19da2007-09-10 21:51:02 +0000663 def getpeercert(self, binary_form=False):
Bill Janssen24bccf22007-08-30 17:07:28 +0000664 """Returns a formatted version of the data in the
665 certificate provided by the other end of the SSL channel.
666 Return None if no certificate was provided, {} if a
667 certificate was provided, but not validated."""
668
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500669 self._checkClosed()
670 self._check_connected()
Bill Janssen98d19da2007-09-10 21:51:02 +0000671 return self._sslobj.peer_certificate(binary_form)
672
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500673 def selected_npn_protocol(self):
674 self._checkClosed()
675 if not self._sslobj or not _ssl.HAS_NPN:
676 return None
677 else:
678 return self._sslobj.selected_npn_protocol()
Bill Janssen98d19da2007-09-10 21:51:02 +0000679
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -0500680 def selected_alpn_protocol(self):
681 self._checkClosed()
682 if not self._sslobj or not _ssl.HAS_ALPN:
683 return None
684 else:
685 return self._sslobj.selected_alpn_protocol()
686
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500687 def cipher(self):
688 self._checkClosed()
Bill Janssen98d19da2007-09-10 21:51:02 +0000689 if not self._sslobj:
690 return None
691 else:
692 return self._sslobj.cipher()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000693
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500694 def compression(self):
695 self._checkClosed()
696 if not self._sslobj:
697 return None
698 else:
699 return self._sslobj.compression()
700
Ezio Melottib01f5e62010-01-18 09:10:26 +0000701 def send(self, data, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500702 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000703 if self._sslobj:
704 if flags != 0:
705 raise ValueError(
706 "non-zero flags not allowed in calls to send() on %s" %
707 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500708 try:
709 v = self._sslobj.write(data)
710 except SSLError as x:
711 if x.args[0] == SSL_ERROR_WANT_READ:
712 return 0
713 elif x.args[0] == SSL_ERROR_WANT_WRITE:
714 return 0
Bill Janssen934b16d2008-06-28 22:19:33 +0000715 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500716 raise
717 else:
718 return v
Bill Janssen426ea0a2007-08-29 22:35:05 +0000719 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000720 return self._sock.send(data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000721
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000722 def sendto(self, data, flags_or_addr, addr=None):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500723 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000724 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000725 raise ValueError("sendto not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000726 self.__class__)
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000727 elif addr is None:
728 return self._sock.sendto(data, flags_or_addr)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000729 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000730 return self._sock.sendto(data, flags_or_addr, addr)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000731
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500732
Ezio Melottib01f5e62010-01-18 09:10:26 +0000733 def sendall(self, data, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500734 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000735 if self._sslobj:
736 if flags != 0:
737 raise ValueError(
738 "non-zero flags not allowed in calls to sendall() on %s" %
739 self.__class__)
Bill Janssen934b16d2008-06-28 22:19:33 +0000740 amount = len(data)
741 count = 0
742 while (count < amount):
743 v = self.send(data[count:])
744 count += v
745 return amount
Bill Janssen426ea0a2007-08-29 22:35:05 +0000746 else:
747 return socket.sendall(self, data, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000748
Ezio Melottib01f5e62010-01-18 09:10:26 +0000749 def recv(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500750 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000751 if self._sslobj:
752 if flags != 0:
753 raise ValueError(
Antoine Pitrou448da712010-03-21 19:33:38 +0000754 "non-zero flags not allowed in calls to recv() on %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000755 self.__class__)
Antoine Pitrou448da712010-03-21 19:33:38 +0000756 return self.read(buflen)
Bill Janssen426ea0a2007-08-29 22:35:05 +0000757 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000758 return self._sock.recv(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000759
Ezio Melottib01f5e62010-01-18 09:10:26 +0000760 def recv_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500761 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000762 if buffer and (nbytes is None):
763 nbytes = len(buffer)
764 elif nbytes is None:
765 nbytes = 1024
766 if self._sslobj:
767 if flags != 0:
768 raise ValueError(
769 "non-zero flags not allowed in calls to recv_into() on %s" %
770 self.__class__)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500771 return self.read(nbytes, buffer)
Bill Janssen61c001a2008-09-08 16:37:24 +0000772 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000773 return self._sock.recv_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000774
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000775 def recvfrom(self, buflen=1024, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500776 self._checkClosed()
Bill Janssen426ea0a2007-08-29 22:35:05 +0000777 if self._sslobj:
Bill Janssen934b16d2008-06-28 22:19:33 +0000778 raise ValueError("recvfrom not allowed on instances of %s" %
Bill Janssen426ea0a2007-08-29 22:35:05 +0000779 self.__class__)
780 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000781 return self._sock.recvfrom(buflen, flags)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000782
Ezio Melottib01f5e62010-01-18 09:10:26 +0000783 def recvfrom_into(self, buffer, nbytes=None, flags=0):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500784 self._checkClosed()
Bill Janssen61c001a2008-09-08 16:37:24 +0000785 if self._sslobj:
786 raise ValueError("recvfrom_into not allowed on instances of %s" %
787 self.__class__)
788 else:
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000789 return self._sock.recvfrom_into(buffer, nbytes, flags)
Bill Janssen61c001a2008-09-08 16:37:24 +0000790
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500791
Ezio Melottib01f5e62010-01-18 09:10:26 +0000792 def pending(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500793 self._checkClosed()
Bill Janssen934b16d2008-06-28 22:19:33 +0000794 if self._sslobj:
795 return self._sslobj.pending()
796 else:
797 return 0
798
Ezio Melottib01f5e62010-01-18 09:10:26 +0000799 def shutdown(self, how):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500800 self._checkClosed()
Bill Janssen296a59d2007-09-16 22:06:00 +0000801 self._sslobj = None
Bill Janssen426ea0a2007-08-29 22:35:05 +0000802 socket.shutdown(self, how)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000803
Ezio Melottib01f5e62010-01-18 09:10:26 +0000804 def close(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000805 if self._makefile_refs < 1:
806 self._sslobj = None
807 socket.close(self)
808 else:
809 self._makefile_refs -= 1
810
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500811 def unwrap(self):
812 if self._sslobj:
813 s = self._sslobj.shutdown()
814 self._sslobj = None
815 return s
816 else:
817 raise ValueError("No SSL wrapper around " + str(self))
Bill Janssen934b16d2008-06-28 22:19:33 +0000818
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500819 def _real_close(self):
820 self._sslobj = None
821 socket._real_close(self)
822
823 def do_handshake(self, block=False):
Bill Janssen934b16d2008-06-28 22:19:33 +0000824 """Perform a TLS/SSL handshake."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500825 self._check_connected()
826 timeout = self.gettimeout()
827 try:
828 if timeout == 0.0 and block:
829 self.settimeout(None)
830 self._sslobj.do_handshake()
831 finally:
832 self.settimeout(timeout)
Bill Janssen934b16d2008-06-28 22:19:33 +0000833
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500834 if self.context.check_hostname:
835 if not self.server_hostname:
836 raise ValueError("check_hostname needs server_hostname "
837 "argument")
838 match_hostname(self.getpeercert(), self.server_hostname)
Bill Janssen934b16d2008-06-28 22:19:33 +0000839
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500840 def _real_connect(self, addr, connect_ex):
841 if self.server_side:
842 raise ValueError("can't connect in server-side mode")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000843 # Here we assume that the socket is client-side, and not
844 # connected at the time of the call. We connect it, then wrap it.
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000845 if self._connected:
Bill Janssen98d19da2007-09-10 21:51:02 +0000846 raise ValueError("attempt to connect already-connected SSLSocket!")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500847 self._sslobj = self.context._wrap_socket(self._sock, False, self.server_hostname, ssl_sock=self)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000848 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500849 if connect_ex:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100850 rc = socket.connect_ex(self, addr)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000851 else:
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100852 rc = None
853 socket.connect(self, addr)
854 if not rc:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500855 self._connected = True
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100856 if self.do_handshake_on_connect:
857 self.do_handshake()
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100858 return rc
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500859 except (OSError, ValueError):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100860 self._sslobj = None
861 raise
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000862
863 def connect(self, addr):
864 """Connects to remote ADDR, and then wraps the connection in
865 an SSL channel."""
866 self._real_connect(addr, False)
867
868 def connect_ex(self, addr):
869 """Connects to remote ADDR, and then wraps the connection in
870 an SSL channel."""
871 return self._real_connect(addr, True)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000872
873 def accept(self):
Bill Janssen24bccf22007-08-30 17:07:28 +0000874 """Accepts a new connection from a remote client, and returns
875 a tuple containing that new connection wrapped with a server-side
876 SSL channel, and the address of the remote client."""
877
Bill Janssen426ea0a2007-08-29 22:35:05 +0000878 newsock, addr = socket.accept(self)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500879 newsock = self.context.wrap_socket(newsock,
880 do_handshake_on_connect=self.do_handshake_on_connect,
881 suppress_ragged_eofs=self.suppress_ragged_eofs,
882 server_side=True)
883 return newsock, addr
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000884
Bill Janssen296a59d2007-09-16 22:06:00 +0000885 def makefile(self, mode='r', bufsize=-1):
886
Bill Janssen61c001a2008-09-08 16:37:24 +0000887 """Make and return a file-like object that
888 works with the SSL connection. Just use the code
889 from the socket module."""
Bill Janssen296a59d2007-09-16 22:06:00 +0000890
Bill Janssen934b16d2008-06-28 22:19:33 +0000891 self._makefile_refs += 1
Antoine Pitroub558f172010-04-23 23:25:45 +0000892 # close=True so as to decrement the reference count when done with
893 # the file-like object.
894 return _fileobject(self, mode, bufsize, close=True)
Bill Janssen296a59d2007-09-16 22:06:00 +0000895
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500896 def get_channel_binding(self, cb_type="tls-unique"):
897 """Get channel binding data for current connection. Raise ValueError
898 if the requested `cb_type` is not supported. Return bytes of the data
899 or None if the data is not available (e.g. before the handshake).
900 """
901 if cb_type not in CHANNEL_BINDING_TYPES:
902 raise ValueError("Unsupported channel binding type")
903 if cb_type != "tls-unique":
904 raise NotImplementedError(
905 "{0} channel binding type not implemented"
906 .format(cb_type))
907 if self._sslobj is None:
908 return None
909 return self._sslobj.tls_unique_cb()
Bill Janssen296a59d2007-09-16 22:06:00 +0000910
Alex Gaynore98205d2014-09-04 13:33:22 -0700911 def version(self):
912 """
913 Return a string identifying the protocol version used by the
914 current SSL channel, or None if there is no established channel.
915 """
916 if self._sslobj is None:
917 return None
918 return self._sslobj.version()
919
Bill Janssen296a59d2007-09-16 22:06:00 +0000920
Bill Janssen98d19da2007-09-10 21:51:02 +0000921def wrap_socket(sock, keyfile=None, certfile=None,
922 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen934b16d2008-06-28 22:19:33 +0000923 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
924 do_handshake_on_connect=True,
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500925 suppress_ragged_eofs=True,
926 ciphers=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000927
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500928 return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000929 server_side=server_side, cert_reqs=cert_reqs,
Bill Janssen934b16d2008-06-28 22:19:33 +0000930 ssl_version=ssl_version, ca_certs=ca_certs,
931 do_handshake_on_connect=do_handshake_on_connect,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000932 suppress_ragged_eofs=suppress_ragged_eofs,
933 ciphers=ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000934
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000935# some utility functions
936
937def cert_time_to_seconds(cert_time):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500938 """Return the time in seconds since the Epoch, given the timestring
939 representing the "notBefore" or "notAfter" date from a certificate
940 in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale).
Bill Janssen24bccf22007-08-30 17:07:28 +0000941
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500942 "notBefore" or "notAfter" dates must use UTC (RFC 5280).
Bill Janssen24bccf22007-08-30 17:07:28 +0000943
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500944 Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
945 UTC should be specified as GMT (see ASN1_TIME_print())
946 """
947 from time import strptime
948 from calendar import timegm
949
950 months = (
951 "Jan","Feb","Mar","Apr","May","Jun",
952 "Jul","Aug","Sep","Oct","Nov","Dec"
953 )
954 time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT
955 try:
956 month_number = months.index(cert_time[:3].title()) + 1
957 except ValueError:
958 raise ValueError('time data %r does not match '
959 'format "%%b%s"' % (cert_time, time_format))
960 else:
961 # found valid month
962 tt = strptime(cert_time[3:], time_format)
963 # return an integer, the previous mktime()-based implementation
964 # returned a float (fractional seconds are always zero here).
965 return timegm((tt[0], month_number) + tt[2:6])
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000966
Bill Janssen296a59d2007-09-16 22:06:00 +0000967PEM_HEADER = "-----BEGIN CERTIFICATE-----"
968PEM_FOOTER = "-----END CERTIFICATE-----"
969
970def DER_cert_to_PEM_cert(der_cert_bytes):
Bill Janssen296a59d2007-09-16 22:06:00 +0000971 """Takes a certificate in binary DER format and returns the
972 PEM version of it as a string."""
973
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500974 f = base64.standard_b64encode(der_cert_bytes).decode('ascii')
975 return (PEM_HEADER + '\n' +
976 textwrap.fill(f, 64) + '\n' +
977 PEM_FOOTER + '\n')
Bill Janssen296a59d2007-09-16 22:06:00 +0000978
979def PEM_cert_to_DER_cert(pem_cert_string):
Bill Janssen296a59d2007-09-16 22:06:00 +0000980 """Takes a certificate in ASCII PEM format and returns the
981 DER-encoded version of it as a byte sequence"""
982
983 if not pem_cert_string.startswith(PEM_HEADER):
984 raise ValueError("Invalid PEM encoding; must start with %s"
985 % PEM_HEADER)
986 if not pem_cert_string.strip().endswith(PEM_FOOTER):
987 raise ValueError("Invalid PEM encoding; must end with %s"
988 % PEM_FOOTER)
989 d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500990 return base64.decodestring(d.encode('ASCII', 'strict'))
Bill Janssen296a59d2007-09-16 22:06:00 +0000991
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500992def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000993 """Retrieve the certificate from the server at the specified address,
994 and return it as a PEM-encoded string.
995 If 'ca_certs' is specified, validate the server cert against it.
996 If 'ssl_version' is specified, use it in the connection attempt."""
997
998 host, port = addr
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500999 if ca_certs is not None:
Bill Janssen296a59d2007-09-16 22:06:00 +00001000 cert_reqs = CERT_REQUIRED
1001 else:
1002 cert_reqs = CERT_NONE
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001003 context = _create_stdlib_context(ssl_version,
1004 cert_reqs=cert_reqs,
1005 cafile=ca_certs)
1006 with closing(create_connection(addr)) as sock:
1007 with closing(context.wrap_socket(sock)) as sslsock:
1008 dercert = sslsock.getpeercert(True)
Bill Janssen296a59d2007-09-16 22:06:00 +00001009 return DER_cert_to_PEM_cert(dercert)
1010
Ezio Melottib01f5e62010-01-18 09:10:26 +00001011def get_protocol_name(protocol_code):
Victor Stinnerb1241f92011-05-10 01:52:03 +02001012 return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
Bill Janssen296a59d2007-09-16 22:06:00 +00001013
1014
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001015# a replacement for the old socket.ssl function
1016
Ezio Melottib01f5e62010-01-18 09:10:26 +00001017def sslwrap_simple(sock, keyfile=None, certfile=None):
Bill Janssen24bccf22007-08-30 17:07:28 +00001018 """A replacement for the old socket.ssl function. Designed
1019 for compability with Python 2.5 and earlier. Will disappear in
1020 Python 3.0."""
Bill Jansseneb257ac2008-09-29 18:56:38 +00001021 if hasattr(sock, "_sock"):
1022 sock = sock._sock
1023
Benjamin Peterson2f334562014-10-01 23:53:01 -04001024 ctx = SSLContext(PROTOCOL_SSLv23)
1025 if keyfile or certfile:
1026 ctx.load_cert_chain(certfile, keyfile)
1027 ssl_sock = ctx._wrap_socket(sock, server_side=False)
Bill Jansseneb257ac2008-09-29 18:56:38 +00001028 try:
1029 sock.getpeername()
Benjamin Peterson941db4d2008-12-31 04:08:55 +00001030 except socket_error:
Bill Jansseneb257ac2008-09-29 18:56:38 +00001031 # no, no connection yet
1032 pass
1033 else:
1034 # yes, do the handshake
1035 ssl_sock.do_handshake()
1036
Bill Janssen934b16d2008-06-28 22:19:33 +00001037 return ssl_sock