def write(self, data): """Write data to connection Write data as string of bytes. Arguments: data -- buffer containing data to be written Return value: number of bytes actually transmitted """ #Time test by johann try: tInicio = time.time() ret = self._wrap_socket_library_call( lambda: SSL_write(self._ssl.value, data), ERR_WRITE_TIMEOUT) tFim = time.time() if globalvars.handshakeDone: globalvars.tSSLWrite += tFim - tInicio except openssl_error() as err: if err.ssl_error == SSL_ERROR_SYSCALL and err.result == -1: raise_ssl_error(ERR_PORT_UNREACHABLE, err) raise if ret: self._handshake_done = True return ret
def do_handshake(self): """Perform a handshake with the peer This method forces an explicit handshake to be performed with either the client or server peer. """ _logger.debug("Initiating handshake...") try: self._wrap_socket_library_call( lambda: SSL_do_handshake(self._ssl.value), ERR_HANDSHAKE_TIMEOUT) except openssl_error() as err: if err.ssl_error == SSL_ERROR_SYSCALL and err.result == -1: raise_ssl_error(ERR_PORT_UNREACHABLE, err) raise self._handshake_done = True _logger.debug("...completed handshake")
def read(self, len=1024, buffer=None): """Read data from connection Read up to len bytes and return them. Arguments: len -- maximum number of bytes to read Return value: string containing read bytes """ try: return self._wrap_socket_library_call( lambda: SSL_read(self._ssl.value, len, buffer), ERR_READ_TIMEOUT) except openssl_error() as err: if err.ssl_error == SSL_ERROR_SYSCALL and err.result == -1: raise_ssl_error(ERR_PORT_UNREACHABLE, err) raise
def _config_ssl_ctx(self, verify_mode): SSL_CTX_set_verify(self._ctx.value, verify_mode) SSL_CTX_set_read_ahead(self._ctx.value, 1) # Compression occurs at the stream layer now, leading to datagram # corruption when packet loss occurs SSL_CTX_set_options(self._ctx.value, SSL_OP_NO_COMPRESSION) if self._certfile: SSL_CTX_use_certificate_chain_file(self._ctx.value, self._certfile) if self._keyfile: SSL_CTX_use_PrivateKey_file(self._ctx.value, self._keyfile, SSL_FILE_TYPE_PEM) if self._ca_certs: SSL_CTX_load_verify_locations(self._ctx.value, self._ca_certs, None) if self._ciphers: try: SSL_CTX_set_cipher_list(self._ctx.value, self._ciphers) except openssl_error() as err: raise_ssl_error(ERR_NO_CIPHER, err)
def _wrap_socket_library_call(self, call, timeout_error): timeout_sec_start = timeout_sec = self._check_nbio() # Pass the call if the socket is blocking or non-blocking if not timeout_sec: # None (blocking) or zero (non-blocking) return call() start_time = datetime.datetime.now() read_sock = self.get_socket(True) need_select = False while timeout_sec > 0: if need_select: if not select([read_sock], [], [], timeout_sec)[0]: break timeout_sec = timeout_sec_start - \ (datetime.datetime.now() - start_time).total_seconds() try: return call() except openssl_error() as err: if err.ssl_error == SSL_ERROR_WANT_READ: need_select = True continue raise raise_ssl_error(timeout_error)
def write(self, data): """Write data to connection Write data as string of bytes. Arguments: data -- buffer containing data to be written Return value: number of bytes actually transmitted """ try: ret = self._wrap_socket_library_call( lambda: SSL_write(self._ssl.value, data), ERR_WRITE_TIMEOUT) except openssl_error() as err: if err.ssl_error == SSL_ERROR_SYSCALL and err.result == -1: raise_ssl_error(ERR_PORT_UNREACHABLE, err) raise if ret: self._handshake_done = True return ret
def __init__(self, sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version=PROTOCOL_DTLSv1, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None): """Constructor Arguments: these arguments match the ones of the SSLSocket class in the standard library's ssl module """ if keyfile and not certfile or certfile and not keyfile: raise_ssl_error(ERR_BOTH_KEY_CERT_FILES) if server_side and not keyfile: raise_ssl_error(ERR_BOTH_KEY_CERT_FILES_SVR) if cert_reqs != CERT_NONE and not ca_certs: raise_ssl_error(ERR_NO_CERTS) if not ciphers: ciphers = "DEFAULT" self._sock = sock self._keyfile = keyfile self._certfile = certfile self._cert_reqs = cert_reqs self._ca_certs = ca_certs self._do_handshake_on_connect = do_handshake_on_connect self._suppress_ragged_eofs = suppress_ragged_eofs self._ciphers = ciphers self._handshake_done = False self._wbio_nb = self._rbio_nb = False if isinstance(sock, SSLConnection): post_init = self._copy_server() elif isinstance(sock, _UnwrappedSocket): post_init = self._reconnect_unwrapped() else: try: peer_address = sock.getpeername() except socket.error: peer_address = None if server_side: post_init = self._init_server(peer_address) else: post_init = self._init_client(peer_address) SSL_set_bio(self._ssl.value, self._rbio.value, self._wbio.value) self._rbio.disown() self._wbio.disown() if post_init: post_init()
def read(self, len=1024, buffer=None): """Read data from connection Read up to len bytes and return them. Arguments: len -- maximum number of bytes to read Return value: string containing read bytes """ #Time test by Johann try: tInicio = time.time() ret = self._wrap_socket_library_call( lambda: SSL_read(self._ssl.value, len, buffer), ERR_READ_TIMEOUT) tFim = time.time() if globalvars.handshakeDone: globalvars.tSSLRead += tFim - tInicio return ret except openssl_error() as err: if err.ssl_error == SSL_ERROR_SYSCALL and err.result == -1: raise_ssl_error(ERR_PORT_UNREACHABLE, err) raise