def recv_into(self, buffer, nbytes=None, flags=0): """ Read nbytes bytes and place into buffer. If nbytes is 0, read up to full size of buffer. """ self._check_closed("read") self._check_connected() if buffer is None: raise ValueError("buffer cannot be None") if nbytes is None: nbytes = len(buffer) else: nbytes = min(len(buffer), nbytes) if nbytes == 0: return 0 data = _ffi.from_buffer(buffer) length = _lib.wolfSSL_read(self.native_object, data, nbytes) if length < 0: err = _lib.wolfSSL_get_error(self.native_object, 0) if err == _SSL_ERROR_WANT_READ: raise SSLWantReadError() else: raise SSLError("wolfSSL_read error (%d)" % err) return length
def do_handshake(self, block=False): # pylint: disable=unused-argument """ Perform a TLS/SSL handshake. """ self._check_closed("do_handshake") self._check_connected() if self._server_side: ret = _lib.wolfSSL_accept(self.native_object) else: ret = _lib.wolfSSL_connect(self.native_object) if ret != _SSL_SUCCESS: err = _lib.wolfSSL_get_error(self.native_object, 0) if err == _SSL_ERROR_WANT_READ: raise SSLWantReadError() elif err == _SSL_ERROR_WANT_WRITE: raise SSLWantWriteError() else: eBuf = _ffi.new("char[80]") eStr = _ffi.string(_lib.wolfSSL_ERR_error_string( err, eBuf)).decode("ascii") if 'ASN no signer error to confirm' in eStr or err is -188: # Some Python ssl consumers explicitly check error message # for 'certificate verify failed' raise SSLError("do_handshake failed with error %d, " "certificate verify failed" % err) # get alert code and string to put in exception msg alertHistoryPtr = _ffi.new("WOLFSSL_ALERT_HISTORY*") alertRet = _lib.wolfSSL_get_alert_history( self.native_object, alertHistoryPtr) if alertRet == _SSL_SUCCESS: alertHistory = alertHistoryPtr[0] code = alertHistory.last_rx.code alertDesc = _lib.wolfSSL_alert_type_string_long(code) if alertDesc != _ffi.NULL: alertStr = _ffi.string(alertDesc).decode("ascii") else: alertStr = '' raise SSLError("do_handshake failed with error %d: %s. " "alert (%d): %s" % (err, eStr, code, alertStr)) else: raise SSLError("do_handshake failed with error %d: %s" % (err, eStr))
def sendall(self, data, flags=0): if flags != 0: raise NotImplementedError("non-zero flags not allowed in calls to " "sendall() on %s" % self.__class__) length = len(data) sent = 0 while sent < length: ret = self.write(data[sent:]) if (ret < 0): err = _lib.wolfSSL_get_error(self.native_object, 0) if err == _SSL_ERROR_WANT_WRITE: raise SSLWantWriteError() else: raise SSLError("wolfSSL_write error (%d)" % err) sent += ret return None
def read(self, length=1024, buffer=None): """ Read up to LENGTH bytes and return them. Return zero-length string on EOF. """ self._check_closed("read") self._check_connected() if buffer is not None: raise ValueError("buffer not allowed in calls to " "read() on %s" % self.__class__) data = _ffi.new('byte[%d]' % length) length = _lib.wolfSSL_read(self.native_object, data, length) if length < 0: err = _lib.wolfSSL_get_error(self.native_object, 0) if err == _SSL_ERROR_WANT_READ: raise SSLWantReadError() else: raise SSLError("wolfSSL_read error (%d)" % err) return _ffi.buffer(data, length)[:] if length > 0 else b''