def ssl_wrap_socket(sock, keyfile = None, certfile = None, cert_reqs = None, ca_certs = None, server_hostname = None, ssl_version = None, ca_cert_dir = None): ctx = OpenSSL.SSL.Context(_openssl_versions[ssl_version]) if certfile: keyfile = keyfile or certfile ctx.use_certificate_file(certfile) if keyfile: ctx.use_privatekey_file(keyfile) if cert_reqs != ssl.CERT_NONE: ctx.set_verify(_openssl_verify[cert_reqs], _verify_callback) if ca_certs or ca_cert_dir: try: ctx.load_verify_locations(ca_certs, ca_cert_dir) except OpenSSL.SSL.Error as e: raise ssl.SSLError('bad ca_certs: %r' % ca_certs, e) else: ctx.set_default_verify_paths() OP_NO_COMPRESSION = 131072 ctx.set_options(OP_NO_COMPRESSION) ctx.set_cipher_list(DEFAULT_SSL_CIPHER_LIST) cnx = OpenSSL.SSL.Connection(ctx, sock) if isinstance(server_hostname, six.text_type): server_hostname = server_hostname.encode('utf-8') cnx.set_tlsext_host_name(server_hostname) cnx.set_connect_state() while True: try: cnx.do_handshake() except OpenSSL.SSL.WantReadError: rd, _, _ = select.select([sock], [], [], sock.gettimeout()) if not rd: raise timeout('select timed out') continue except OpenSSL.SSL.Error as e: raise ssl.SSLError('bad handshake: %r' % e) break return WrappedSocket(cnx, sock)
def connect(self): sock = socket.create_connection((self.host, self.port), self.timeout) if self._tunnel_host: self.sock = sock self._tunnel() self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, \ cert_reqs = ssl.CERT_REQUIRED, ca_certs = CA_CERTS, \ ssl_version = ssl.PROTOCOL_TLSv1) cert = self.sock.getpeercert() if not self._verify_hostname(self.host, cert): raise ssl.SSLError('Failed to verify hostname')
def _verify_cert(self, sock, ca_certs): # If they asked us to not verify the Certificate then nothing to do if not ca_certs: return # Retrieve the Existing Certificates from the File in Binary Form peercert = sock.getpeercert(True) try: with open(ca_certs, 'r') as f: certs_str = f.read() except Exception: raise ssl.SSLError( _("Failed to read certificate from %s") % ca_certs) # Verify the Existing Certificates found = False certs = [match.group(0) for match in _PEM_RE.finditer(certs_str)] for cert in certs: existcert = ssl.PEM_cert_to_DER_cert(cert) # First check to make sure the 2 certificates are the same ones if (hashlib.sha256(existcert).digest() == hashlib.sha256( peercert).digest()): found = True break if not found: raise ssl.SSLError( _("The certificate doesn't match the trusted one " "in %s.") % ca_certs) if load_certificate is None and FILETYPE_ASN1 is None: raise ssl.SSLError( _("Missing 'pyOpenSSL' python module, ensure the " "library is installed.")) # Throw an exception if the certificate given to us has expired x509 = load_certificate(FILETYPE_ASN1, peercert) if x509.has_expired(): raise ssl.SSLError( _("The certificate expired: %s") % x509.get_notAfter())
def exc_wrap(func, *args, **kwargs): try: return func(*args, **kwargs) except nss.error.NSPRError as e: if e.error_desc.startswith('(SEC_ERROR_') or e.error_desc.startswith( '(SSL_ERROR_'): raise basessl.SSLError(0, e.error_message or e.error_desc, e) for k in ERROR_MAP: if k == e.error_code: raise ERROR_MAP[k][0] raise
def test_galaxy_api_lookup_repo_by_name_SSLError(mocker, galaxy_api): mocker.patch('ansible_galaxy.rest_api.open_url', side_effect=ssl.SSLError('ssl stuff broke... good luck and godspeed.')) try: galaxy_api.lookup_repo_by_name('some-test-namespace', 'some-test-name') except exceptions.GalaxyClientAPIConnectionError as e: log.exception(e) log.debug(e) return assert False, 'Excepted to get a GalaxyClientAPIConnectionError here but did not.'
def test_Verified_HTTPSConnection_two_way_ssl_connect(self, wrap_socket_mock, create_connection_mock, init_security_mock): wrap_socket_mock.side_effect=ssl.SSLError() connection = security.VerifiedHTTPSConnection("example.com", self.config.get('server', 'secured_url_port'), self.config) connection._tunnel_host = False connection.sock = None try: connection.connect() except ssl.SSLError: pass self.assertTrue(init_security_mock.called)
def read(self, size): """Read 'size' bytes from remote.""" # sslobj.read() sometimes returns < size bytes chunks = [] read = 0 while read < size: data = self.sslobj.read(min(size-read, 16384)) if not data: raise ssl.SSLError(ssl.SSL_ERROR_EOF) read += len(data) chunks.append(data) return ''.join(chunks)
def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, ca_certs=None, server_hostname=None, ssl_version=None): ctx = OpenSSL.SSL.Context(_openssl_versions[ssl_version]) if certfile: ctx.use_certificate_file(certfile) if keyfile: ctx.use_privatekey_file(keyfile) if cert_reqs != ssl.CERT_NONE: ctx.set_verify(_openssl_verify[cert_reqs], _verify_callback) if ca_certs: try: ctx.load_verify_locations(ca_certs, None) except OpenSSL.SSL.Error as e: raise ssl.SSLError('bad ca_certs: %r' % ca_certs, e) else: ctx.set_default_verify_paths() # Disable TLS compression to migitate CRIME attack (issue #309) OP_NO_COMPRESSION = 0x20000 ctx.set_options(OP_NO_COMPRESSION) # Set list of supported ciphersuites. ctx.set_cipher_list(DEFAULT_SSL_CIPHER_LIST) cnx = OpenSSL.SSL.Connection(ctx, sock) cnx.set_tlsext_host_name(server_hostname) cnx.set_connect_state() while True: try: cnx.do_handshake() except OpenSSL.SSL.WantReadError: select.select([sock], [], []) continue except OpenSSL.SSL.Error as e: raise ssl.SSLError('bad handshake', e) break return WrappedSocket(cnx, sock)
def connect(self): """ Overridden connect() method to wrap the socket using an SSLSocket, and check the server certificates. """ try: self.sock = socket.create_connection((self.host, self.port)) except AttributeError: HTTPSConnection.connect(self) if not _have_ssl: # No SSL available - insecure connection print("WARNING: No SSL support - connection may be insecure") elif self.ca_certs: # Wrap the socket in an SSLSocket, and tell it to validate # the server certificates. Note that this does not check that # the certificate's host matches, so we must do that ourselves. self.sock = ssl.wrap_socket(self.sock, ca_certs=self.ca_certs, cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_TLSv1) cert = self.sock.getpeercert() cert_hosts = [] host_valid = False if "subject" in cert: for x in cert["subject"]: if x[0][0] == "commonName": cert_hosts.append(x[0][1]) if "subjectAltName" in cert: for x in cert["subjectAltName"]: if x[0] == "dns": cert_hosts.append(x[1]) for cert_host in cert_hosts: if self.host.startswith(cert_host): host_valid = True if not host_valid: raise ssl.SSLError("Host name '%s' doesn't match "\ "certificate host %s"\ % (self.host, str(cert_hosts))) else: # No CA certificates supplied, so can't validate the server # certificates, but we still wrap the socket in an SSLSocket # so that all data is encrypted. self.sock = ssl.wrap_socket(self.sock, ca_certs=None, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1)
def get_ip_info(self, ip, server_name=None, callback=None, conntimeout=g_conntimeout, handshaketimeout=g_handshaketimeout, timeout=g_timeout): retry = None server_name = server_name or self.server_name callback = callback or self.check_type_status while True: start_time = time() ssl_time = 1e5 type = None domain = None sock = None ssl_sock = None try: sock = http_gws.get_tcp_socket(ip) http_gws.set_tcp_socket(sock, set_buffer=False) ssl_sock = http_gws.get_ssl_socket(sock, server_name) ssl_sock.settimeout(conntimeout) ssl_sock.connect((ip, 443)) ssl_sock.settimeout(handshaketimeout) ssl_sock.do_handshake() ssl_sock.settimeout(timeout) handshaked_time = time() - start_time ssl_time = int(handshaked_time * 1000) if handshaked_time > handshaketimeout: raise socket.error('handshake 超时:%d ms' % ssl_time) cert = http_gws.google_verify(ssl_sock) domain = cert.get_subject().CN if not domain: raise ssl.SSLError('%s 无法获取 commonName:%s' % (ip, cert)) type = callback(ssl_sock, ip) except NetWorkIOError as e: self.logger.debug('get_ip_info 发生错误:%s', e) if not retry and (e.args == zero_EOF_error or e.args[0] in zero_errno): retry = True continue finally: if ssl_sock: ssl_sock.close() elif sock: sock.close() if server_name is self.server_name and domain == self.com_domain: domain = '*.google.com' if type is 'gae' and not self.test_ip_gae(ip): type = None return domain, ssl_time, type
def _cert_array_from_pem(pem_bundle): """ Given a bundle of certs in PEM format, turns them into a CFArray of certs that can be used to validate a cert chain. """ der_certs = [ base64.b64decode(match.group(1)) for match in _PEM_CERTS_RE.finditer(pem_bundle) ] if not der_certs: raise ssl.SSLError("No root certificates specified") cert_array = CoreFoundation.CFArrayCreateMutable( CoreFoundation.kCFAllocatorDefault, 0, ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks)) if not cert_array: raise ssl.SSLError("Unable to allocate memory!") try: for der_bytes in der_certs: certdata = _cf_data_from_bytes(der_bytes) if not certdata: raise ssl.SSLError("Unable to allocate memory!") cert = Security.SecCertificateCreateWithData( CoreFoundation.kCFAllocatorDefault, certdata) CoreFoundation.CFRelease(certdata) if not cert: raise ssl.SSLError("Unable to build cert object!") CoreFoundation.CFArrayAppendValue(cert_array, cert) CoreFoundation.CFRelease(cert) except Exception: # We need to free the array before the exception bubbles further. # We only want to do that if an error occurs: otherwise, the caller # should free. CoreFoundation.CFRelease(cert_array) return cert_array
def verify_peer(remote_host, peer_certificate): """ check_hostname() Checks the hostname being accessed against the various hostnames present in the remote certificate """ hostnames = set() wildcard_hostnames = set() for subject in peer_certificate['subject']: if 'commonName' == subject[0] and len(subject) > 1: hostname = subject[1].encode('utf-8') wch_tuple = tuple(hostname.split('.')) if -1 != wch_tuple[0].find('*'): wildcard_hostnames.add(wch_tuple) else: hostnames.add(hostname) # Get the subject alternative names out of the certificate try: sans = (x for x in peer_certificate['subjectAltName'] if x[0] == 'DNS') for san in sans: if len(san) > 1: wch_tuple = tuple(san[1].split('.')) if -1 != wch_tuple[0].find('*'): wildcard_hostnames.add(wch_tuple) else: hostnames.add(san[1]) except KeyError: pass if remote_host not in hostnames: wildcard_match = False rh_tuple = tuple(remote_host.split('.')) for wch_tuple in wildcard_hostnames: l = len(wch_tuple) if len(rh_tuple) == l: l -= 1 rhparts_match = True while l < 0: if rh_tuple[l] != wch_tuple[l]: rhparts_match = False break if rhparts_match and fnmatch(rh_tuple[0], wch_tuple[0]): wildcard_match = True if not wildcard_match: raise ssl.SSLError( 'hostname "%s" doesn\'t match certificate name(s) "%s"' % (remote_host, ', '.join(hostnames)))
def getpeercert(self, binary_form=False): x509 = self.connection.get_peer_certificate() if not x509: raise ssl.SSLError('') if binary_form: return OpenSSL.crypto.dump_certificate( OpenSSL.crypto.FILETYPE_ASN1, x509) return { 'subject': ((('commonName', x509.get_subject().CN), ), ), 'subjectAltName': [('DNS', value) for value in get_subj_alt_name(x509)] }
def test_mixed_message_and_buffer_sizes(self): """ Validate that all messages are processed with different scenarios: - various message sizes - various socket buffer sizes - random non-fatal errors raised """ c = self.make_connection() c.process_io_buffer = Mock() errors = cycle([ ssl.SSLError(ssl.SSL_ERROR_WANT_READ), ssl.SSLError(ssl.SSL_ERROR_WANT_WRITE), socket_error(errno.EWOULDBLOCK), socket_error(errno.EAGAIN) ]) for buffer_size in [512, 1024, 2048, 4096, 8192]: c.in_buffer_size = buffer_size for i in range(1, 15): c.process_io_buffer.reset_mock() c._iobuf = io.BytesIO() message = io.BytesIO(six.b('a') * (2**i)) def recv_side_effect(*args): if random.randint(1, 10) % 3 == 0: raise next(errors) return message.read(args[0]) self.get_socket(c).recv.side_effect = recv_side_effect c.handle_read(*self.null_handle_function_args) if c._iobuf.tell(): c.process_io_buffer.assert_called_once() else: c.process_io_buffer.assert_not_called()
def connect(self): # overrides the version in httplib so that we do certificate verification if sys.hexversion >= 0x02070000: sock = socket.create_connection((self.host, self.port), self.timeout, self.source_address) else: sock = socket.create_connection((self.host, self.port), self.timeout) if self._tunnel_host: self.sock = sock self._tunnel() # wrap the socket if sys.hexversion > 0x03010000: server_hostname = self.host if ssl.HAS_SNI else None self.sock = self._context.wrap_socket( sock, server_hostname=server_hostname) else: self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file) # verify the certificate fingerprint try: certificate = self.sock.getpeercert(True) if certificate is None: raise ssl.SSLError("Certificate validation failed") else: fingerprint = hashlib.sha1(certificate).hexdigest() fingerprint = ":".join([ "".join(x) for x in izip_longest(*[iter(fingerprint.upper())] * 2) ]) if fingerprint not in VerifiedHTTPSConnection.VALID_FINGERPRINTS: raise ssl.SSLError("Certificate validation failed") except Exception: self.sock.shutdown(socket.SHUT_RDWR) self.sock.close() raise
def test_context_is_reset_after_request_has_finished(self): context = {'foo': 'bar'} def responseCls(connection, response): connection.called = True self.assertEqual(connection.context, context) con = Connection() con.called = False con.connection = Mock() con.responseCls = responseCls con.set_context(context) self.assertEqual(con.context, context) con.request('/') # Context should have been reset self.assertTrue(con.called) self.assertEqual(con.context, {}) # Context should also be reset if a method inside request throws con = Connection() con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.connection.request = Mock(side_effect=ssl.SSLError()) try: con.request('/') except ssl.SSLError: pass self.assertEqual(con.context, {}) con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.responseCls = Mock(side_effect=ValueError()) try: con.request('/') except ValueError: pass self.assertEqual(con.context, {})
def test_context_is_reset_after_request_has_finished(self): context = {"foo": "bar"} def responseCls(connection, response) -> mock.MagicMock: connection.called = True self.assertEqual(connection.context, context) return mock.MagicMock(spec=Response) con = Connection() con.called = False con.connection = Mock() con.responseCls = responseCls con.set_context(context) self.assertEqual(con.context, context) con.request("/") # Context should have been reset self.assertTrue(con.called) self.assertEqual(con.context, {}) # Context should also be reset if a method inside request throws con = Connection(timeout=1, retry_delay=0.1) con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.connection.request = Mock(side_effect=ssl.SSLError()) try: con.request("/") except ssl.SSLError: pass self.assertEqual(con.context, {}) con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.responseCls = Mock(side_effect=ValueError()) try: con.request("/") except ValueError: pass self.assertEqual(con.context, {})
def _tls_match_hostname(self, ssl_sock): try: cert = ssl_sock.getpeercert() except AttributeError: # the getpeercert can throw Attribute error: object has no attribute 'peer_certificate' # Don't let that crash the whole client. See also: http://bugs.python.org/issue13721 raise ssl.SSLError('Not connected') san = cert.get('subjectAltName') if san: have_san_dns = False for (key, value) in san: if key == 'DNS': have_san_dns = True if self._host_matches_cert(self._host.lower(), value.lower()) == True: return if key == 'IP Address': have_san_dns = True if value.lower() == self._host.lower(): return if have_san_dns: # Only check subject if subjectAltName dns not found. raise ssl.SSLError( 'Certificate subject does not match remote hostname.') subject = cert.get('subject') if subject: for ((key, value), ) in subject: if key == 'commonName': if self._host_matches_cert(self._host.lower(), value.lower()) == True: return raise ssl.SSLError( 'Certificate subject does not match remote hostname.')
def version(self): protocol = Security.SSLProtocol() result = Security.SSLGetNegotiatedProtocolVersion( self.context, ctypes.byref(protocol)) _assert_no_error(result) if protocol.value == SecurityConst.kTLSProtocol13: raise ssl.SSLError("SecureTransport does not support TLS 1.3") elif protocol.value == SecurityConst.kTLSProtocol12: return "TLSv1.2" elif protocol.value == SecurityConst.kTLSProtocol11: return "TLSv1.1" elif protocol.value == SecurityConst.kTLSProtocol1: return "TLSv1" elif protocol.value == SecurityConst.kSSLProtocol3: return "SSLv3" elif protocol.value == SecurityConst.kSSLProtocol2: return "SSLv2" else: raise ssl.SSLError("Unknown TLS version: %r" % protocol)
def test_certSigningFailed(self, dumpsMock, loadsMock, sleepMock, pformatMock): register = MagicMock() self.controller.register = register dumpsMock.return_value = "request" response = {"responseId":1,} loadsMock.return_value = response self.controller.sendRequest = Mock(side_effect=ssl.SSLError()) self.controller.repeatRegistration=True self.controller.registerWithServer() #Conroller thread and the agent stop if the repeatRegistration flag is False self.assertFalse(self.controller.repeatRegistration)
def test_galaxy_api_get_collection_detail_SSLError(mocker, galaxy_api): mocker.patch( 'ansible_galaxy.rest_api.requests.Session.request', side_effect=ssl.SSLError('ssl stuff broke... good luck and godspeed.')) try: galaxy_api.get_collection_detail('some-test-namespace', 'some-test-name') except exceptions.GalaxyClientAPIConnectionError as e: log.exception(e) log.debug(e) return assert False, 'Excepted to get a GalaxyClientAPIConnectionError here but did not.'
def load_cert_chain( self, certfile: str, keyfile: Optional[str] = None, password: Optional[str] = None, ) -> None: try: self._ctx.use_certificate_chain_file(certfile) if password is not None: if not isinstance(password, bytes): password = password.encode("utf-8") # type: ignore[assignment] self._ctx.set_passwd_cb(lambda *_: password) self._ctx.use_privatekey_file(keyfile or certfile) except OpenSSL.SSL.Error as e: raise ssl.SSLError(f"Unable to load certificate chain: {e!r}") from e
def load_verify_locations( self, cafile: Optional[str] = None, capath: Optional[str] = None, cadata: Optional[bytes] = None, ) -> None: if cafile is not None: cafile = cafile.encode("utf-8") # type: ignore[assignment] if capath is not None: capath = capath.encode("utf-8") # type: ignore[assignment] try: self._ctx.load_verify_locations(cafile, capath) if cadata is not None: self._ctx.load_verify_locations(BytesIO(cadata)) except OpenSSL.SSL.Error as e: raise ssl.SSLError(f"unable to load trusted certificates: {e!r}") from e
def validate_certificate_chain(self, der_certs): """ Validate a given certificate chain which should be full, as a list of DER (binary) certificates from leaf to root (in this order and including both), raising an ``ssl.SSLError`` when the chain isn't valid. This method requires OpenSSL, which should be available from the command line. """ with ExitStack() as stack: def new_pem_file(data): pf = stack.enter_context( NamedTemporaryFile("wb", suffix=".pem"), ) pf.write(data.encode("ascii")) pf.flush() return pf pem_certs = [ssl.DER_cert_to_PEM_cert(dc) for dc in der_certs] target_pem = new_pem_file(pem_certs[0]) intermediary_pem = new_pem_file("".join(pem_certs[1:-1])) root_pem = new_pem_file(pem_certs[-1]) command_line = [ "openssl", "verify", "-CAfile", root_pem.name, "-untrusted", intermediary_pem.name, target_pem.name, ] openssl_proc = Popen(command_line, stdout=PIPE, stderr=PIPE) openssl_proc.wait() # Logs the OpenSSL results logger.debug("OpenSSL certificate chain validation results:") for stream_name in ["stdout", "stderr"]: msg = getattr(openssl_proc, stream_name).read() if msg.strip(): for line in msg.decode("ascii").splitlines(): logger.debug(f"[{stream_name}] {line}") logger.debug(f"[return code] {openssl_proc.returncode}") if openssl_proc.returncode != 0: raise ssl.SSLError("Certificate chain verification failed")
def cert_check(self, host, port): sock = socket.socket() sock.connect((host,port)) sock = ssl.wrap_socket(sock,cert_reqs=ssl.CERT_REQUIRED,ca_certs=RTConnect.CERT_FILE) cert = sock.getpeercert() for field in cert['subject']: if field[0][0] == 'commonName': certhost = field[0][1] if certhost != host: raise ssl.SSLError("Host name '%s' doesn't match certificate host '%s'" % (host, certhost)) else: return True return False
def recv_into(self, *args, **kwargs): try: return self.connection.recv_into(*args, **kwargs) except OpenSSL.SSL.SysCallError as e: if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"): return 0 else: raise SocketError(str(e)) except OpenSSL.SSL.ZeroReturnError: if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: return 0 else: raise # TLS 1.3 post-handshake authentication except OpenSSL.SSL.Error as e: raise ssl.SSLError("read error: %r" % e)
def test_error_if_short_key(self, mock_load_cert_chain): mock_load_cert_chain.side_effect = ssl.SSLError( # These are the real args of the exception. 336245135, "[SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:3542)", ) # 512 cannot be used as we would get an error from FIPS and 1024 is # long enough. So a mock must be used. self.pair.regenerate(SERVER_NAME, 1024) errors = self.pair.check() self.assertEqual( errors, [ "SSL certificate does not match the key: " "[SSL: EE_KEY_TOO_SMALL] ee key too small (_ssl.c:3542)", ], )
def getipinfo(self, ip, conntimeout=g_conntimeout, handshaketimeout=g_handshaketimeout, timeout=g_timeout, retry=None): if ipnotuse(ip): return None, 0, False start_time = time() costtime = 0 domain = None sock = None ssl_sock = None try: sock = socket.socket(socket.AF_INET if ':' not in ip else socket.AF_INET6) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, http_gws.offlinger_val) sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True) ssl_sock = http_gws.get_ssl_socket(sock, g_servername) ssl_sock.settimeout(conntimeout) ssl_sock.connect((ip, 443)) ssl_sock.settimeout(handshaketimeout) ssl_sock.do_handshake() ssl_sock.settimeout(timeout) handshaked_time = time() - start_time if handshaked_time > handshaketimeout: raise socket.error('handshake cost %dms timed out' % int(handshaked_time * 1000)) cert = http_gws.google_verify(ssl_sock) domain = cert.get_subject().CN if not domain: raise ssl.SSLError('%s 无法获取 commonName:%s ' % (ip, cert)) except NetWorkIOError as e: sock.close() ssl_sock = None if not retry and e.args == zero_EOF_error: return self.getipinfo(ip, conntimeout, handshaketimeout, timeout, True) WARNING('getipinfo %r', e) is_gae = self.check_gae_status(ssl_sock, sock, ip) if ssl_sock else False costtime = int((time() - start_time) * 1000) return domain, costtime, is_gae
def recv(self, *args, **kwargs): try: data = self.connection.recv(*args, **kwargs) except OpenSSL.SSL.SysCallError as e: if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"): return b"" else: raise SocketError(str(e)) except OpenSSL.SSL.ZeroReturnError: if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: return b"" else: raise except OpenSSL.SSL.WantReadError: if not util.wait_for_read(self.socket, self.socket.gettimeout()): raise timeout("The read operation timed out") else: return self.recv(*args, **kwargs) # TLS 1.3 post-handshake authentication except OpenSSL.SSL.Error as e: raise ssl.SSLError("read error: %r" % e) else: return data
def connect(self): """ Connect Checks if verification is toggled; if not, just call httplib.HTTPSConnection's connect """ if not self.verify: return httplib.HTTPSConnection.connect(self) # otherwise, create a connection and verify the hostname # use socket.create_connection (in 2.6+) if possible if getattr(socket, 'create_connection', None): sock = socket.create_connection((self.host, self.port), self.timeout) else: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((self.host, self.port)) # Activate the HTTP proxy if self.http_proxy_used: self._activate_http_proxy(sock=sock) ssl_version = libcloud.security.SSL_VERSION try: self.sock = ssl.wrap_socket( sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_REQUIRED, ca_certs=self.ca_cert, ssl_version=ssl_version) except socket.error: exc = sys.exc_info()[1] # Re-throw an exception with a more friendly error message exc = get_socket_error_exception(ssl_version=ssl_version, exc=exc) raise exc cert = self.sock.getpeercert() try: match_hostname(cert, self.host) except CertificateError: e = sys.exc_info()[1] raise ssl.SSLError('Failed to verify hostname: %s' % (str(e)))