예제 #1
0
FLB_INLINE int net_io_tls_write(struct flb_thread *th, struct flb_io_upstream *u,
                     void *data, size_t len, size_t *out_len)
{
    int ret;
    size_t total = 0;

    if (!u->tls_session) {
        u->tls_session = flb_tls_session_new(u->tls->context);
        if (!u->tls_session) {
            flb_error("[io_tls] could not create tls session");
            return -1;
        }

        ret = flb_io_net_tls_connect(u, th);
        if (ret == -1) {
            flb_error("[io_tls] could not connect/initiate TLS session");
            return -1;
        }
    }

 retry_write:
    ret = mbedtls_ssl_write(&u->tls_session->ssl,
                            data + total,
                            len - total);
    if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
        io_tls_event_switch(u, MK_EVENT_WRITE);
        flb_thread_yield(th, FLB_FALSE);
        goto retry_write;
    }
    else if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
        io_tls_event_switch(u, MK_EVENT_READ);
        flb_thread_yield(th, FLB_FALSE);
        goto retry_write;
    }
    else if (ret < 0) {
        char err_buf[72];
        mbedtls_strerror(ret, err_buf, sizeof(err_buf));
        flb_debug("[tls] SSL error: %s", err_buf);

        /* There was an error transmitting data */
        mk_event_del(u->evl, &u->event);
        tls_session_destroy(u->tls_session);
        u->tls_session = NULL;
        return -1;
    }

    /* Update statistics */
    //flb_stats_update(out->stats_fd, ret, 0);

    /* Update counter and check if we need to continue writing */
    total += ret;
    if (total < len) {
        io_tls_event_switch(u, MK_EVENT_WRITE);
        flb_thread_yield(th, FLB_FALSE);
        goto retry_write;
    }

    mk_event_del(u->evl, &u->event);
    return 0;
}
예제 #2
0
파일: mbedtls.c 프로젝트: thors/ircd-ratbox
static ssize_t
rb_ssl_read_or_write(int r_or_w, rb_fde_t *F, void *rbuf, const void *wbuf, size_t count)
{
	ssize_t ret;

	if(r_or_w == 0)
		ret = mbedtls_ssl_read(F->ssl, rbuf, count);
	else
		ret = mbedtls_ssl_write(F->ssl, wbuf, count);

	if(ret < 0)
	{
		switch (ret)
		{
		case MBEDTLS_ERR_SSL_WANT_READ:
			return RB_RW_SSL_NEED_READ;
		case MBEDTLS_ERR_SSL_WANT_WRITE:
			return RB_RW_SSL_NEED_WRITE;
		default:
			F->sslerr.ssl_errno = ret;
			errno = EIO;
			return RB_RW_IO_ERROR;
		}
	}

	return ret;
}
예제 #3
0
unsigned int HAL_DTLSSession_write(DTLSContext *context,
                                   const unsigned char   *p_data,
                                   unsigned int    *p_datalen)
{
    int len  = 0;
    unsigned int err_code = DTLS_SUCCESS;
    dtls_session_t *p_dtls_session = (dtls_session_t *)context;

    if (NULL != p_dtls_session && NULL != p_data && p_datalen != NULL) {
        len = (*p_datalen);
        len = mbedtls_ssl_write(&p_dtls_session->context, p_data, len);

        if (len < 0) {
            if (len == MBEDTLS_ERR_SSL_CONN_EOF) {
                if (p_dtls_session->context.state < MBEDTLS_SSL_HANDSHAKE_OVER) {
                    err_code = DTLS_HANDSHAKE_IN_PROGRESS;
                }
            }
        } else {
            (*p_datalen) = len;
            err_code      = DTLS_SUCCESS;
        }
    }

    return err_code;
}
예제 #4
0
IoT_Error_t iot_tls_write(Network *pNetwork, unsigned char *pMsg, size_t len, Timer *timer, size_t *written_len) {
    size_t written_so_far;
    bool isErrorFlag = false;
    int frags, ret = 0;
    TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams);

    for(written_so_far = 0, frags = 0;
        written_so_far < len && !has_timer_expired(timer); written_so_far += ret, frags++) {
        while(!has_timer_expired(timer) &&
              (ret = mbedtls_ssl_write(&(tlsDataParams->ssl), pMsg + written_so_far, len - written_so_far)) <= 0) {
            if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
                ESP_LOGE(TAG, "failed! mbedtls_ssl_write returned -0x%x", -ret);
                /* All other negative return values indicate connection needs to be reset.
                * Will be caught in ping request so ignored here */
                isErrorFlag = true;
                break;
            }
        }
        if(isErrorFlag) {
            break;
        }
    }

    *written_len = written_so_far;

    if(isErrorFlag) {
        return NETWORK_SSL_WRITE_ERROR;
    } else if(has_timer_expired(timer) && written_so_far != len) {
        return NETWORK_SSL_WRITE_TIMEOUT_ERROR;
    }

    return SUCCESS;
}
예제 #5
0
/*
 * [0] - dukf_ssl_context_t - pointer
 * [1] - data to write - buffer or string
 */
static duk_ret_t js_ssl_write(duk_context *ctx) {
	char errortext[256];
	LOGD(">> js_ssl_write");
	dukf_ssl_context_t *dukf_ssl_context = duk_get_pointer(ctx, -2);
	size_t len;
	uint8_t *buf;

	// If the data is a string, then the string is the data to transmit else it
	// is a buffer and the content of the buffer is the data to transmit,
	if (duk_is_string(ctx, -1)) {
		buf = (void *)duk_get_string(ctx, -1);
		len = strlen((char *)buf);
	} else {
		buf = duk_get_buffer_data(ctx, -1, &len);
		if (len == 0) {
			LOGE("js_ssl_write: The data buffer is zero length.");
			return 0;
		}
	}

	LOGD("About to send data over SSL: %.*s", len, buf);
	int rc = mbedtls_ssl_write(&dukf_ssl_context->ssl, buf, len);
	if (rc < 0) {
		 mbedtls_strerror(rc, errortext, sizeof(errortext));
		 LOGE("error from mbedtls_ssl_write: %d - %x - %s", rc, rc, errortext);
		 duk_push_nan(ctx);
	} else {
		duk_push_int(ctx, rc);
	}
	LOGD("<< js_ssl_write: rc=%d", rc);
	return 1;
} // js_ssl_write
예제 #6
0
/* send packets from TCP socket */
ssize_t send_cb(websocket_context_ptr ctx, const uint8_t *buf, size_t len, int flags, void *user_data)
{
	ssize_t r;
	int fd;
	int retry_cnt = 3;
	struct websocket_info_t *info = user_data;

	fd = info->data->fd;
SEND_RETRY:
	if (info->data->tls_enabled) {
		r = mbedtls_ssl_write(info->data->tls_ssl, buf, len);
	} else {
		r = send(fd, buf, len, flags);
	}

	if (r < 0) {
		printf("send err : %d\n", errno);
		if (retry_cnt == 0) {
			websocket_set_error(info->data, WEBSOCKET_ERR_CALLBACK_FAILURE);
			return r;
		}
		retry_cnt--;
		goto SEND_RETRY;
	}

	return r;
}
ProtocolError DTLSMessageChannel::send(Message& message)
{
  if (ssl_context.state != MBEDTLS_SSL_HANDSHAKE_OVER)
    return INVALID_STATE;

  if (message.send_direct())
  {
	  // send unencrypted
	  int bytes = this->send(message.buf(), message.length());
	  return bytes < 0 ? IO_ERROR : NO_ERROR;
  }

#ifdef DEBUG_BUILD
      LOG(TRACE, "message length %d", message.length());
      for (size_t i=0; i<message.length(); i++)
      {
	  	  char buf[3];
	  	  char c = message.buf()[i];
	  	  sprintf(buf, "%02x", c);
	  	  LOG_PRINT(TRACE, buf);
      }
      LOG_PRINT(TRACE, "\n");
#endif

  int ret = mbedtls_ssl_write(&ssl_context, message.buf(), message.length());
  if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
  {
	  reset_session();
	  return IO_ERROR;
  }
  sessionPersist.update(&ssl_context, callbacks.save, coap_state ? *coap_state : 0);
  return NO_ERROR;
}
예제 #8
0
Socket::Status TcpSocket::send(const void* data, std::size_t size, std::size_t& sent)
{
    // Check the parameters
    if (!data || (size == 0))
    {
        err() << "Cannot send data over the network (no data to send)" << std::endl;
        return Error;
    }

    // Loop until every byte has been sent
    int result = 0;
    for (sent = 0; sent < size; sent += result)
    {
        // Send a chunk of data
        if (isSecure())
            result = mbedtls_ssl_write(&getSecureData().ssl, static_cast<const unsigned char*>(data) + sent, size - sent);
        else
            result = ::send(getHandle(), static_cast<const char*>(data) + sent, size - sent, flags);

        // Check for errors
        if (result < 0)
        {
            Status status = priv::SocketImpl::getErrorStatus();

            if ((status == NotReady) && sent)
                return Partial;

            return status;
        }
    }

    return Done;
}
예제 #9
0
static int send_one_packet(const char *packet_body, mbedtls_ssl_context *ssl) {
  int ret, len;
  unsigned char buf[10000];

  plog("sending packet: '%s'", packet_body);

  len = strlen(packet_body);

  do {
    ret = mbedtls_ssl_write(ssl, (unsigned char *)packet_body, len);
  } while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE);

  if (ret < 0) {
    plog("ERROR: mbedtls_ssl_write returned %d", ret);
    return ret;
  }

  len = ret;
  plog("%d bytes written: '%s'", len, packet_body);

  if (strncmp("noreply", packet_body, 7) == 0) {
    /* Outgoing packet begins with "noreply", so don't attempt to read a
     * response from the server. Just return successfully. */
    return 0;
  }

  plog("Read from server...");

  len = sizeof(buf) - 1;
  memset(buf, 0, sizeof(buf));

  do {
    ret = mbedtls_ssl_read(ssl, buf, len);
  } while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE);

  if (ret <= 0) {
    switch (ret) {
      case MBEDTLS_ERR_SSL_TIMEOUT:
        plog("ERROR: timeout");
        return ret;

      case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
        plog("ERROR: connection was closed gracefully");
        return ret;

      default:
        plog("ERROR: mbedtls_ssl_read returned -0x%x", -ret);
        return ret;
    }
  }

  len = ret;
  plog("%d bytes read: '%s'", len, buf);

  if (is_reverse(packet_body, (char *)buf)) {
    return 0;                   /* Success */
  }
  return -1;
}
예제 #10
0
static int write_ssl_and_get_response( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
{
    int ret;
    unsigned char data[128];
    char code[4];
    size_t i, idx = 0;

    mbedtls_printf("\n%s", buf);
    while( len && ( ret = mbedtls_ssl_write( ssl, buf, len ) ) <= 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
            return -1;
        }
    }

    do
    {
        len = sizeof( data ) - 1;
        memset( data, 0, sizeof( data ) );
        ret = mbedtls_ssl_read( ssl, data, len );

        if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
            continue;

        if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
            return -1;

        if( ret <= 0 )
        {
            mbedtls_printf( "failed\n  ! mbedtls_ssl_read returned %d\n\n", ret );
            return -1;
        }

        mbedtls_printf("\n%s", data);
        len = ret;
        for( i = 0; i < len; i++ )
        {
            if( data[i] != '\n' )
            {
                if( idx < 4 )
                    code[ idx++ ] = data[i];
                continue;
            }

            if( idx == 4 && code[0] >= '0' && code[0] <= '9' && code[3] == ' ' )
            {
                code[3] = '\0';
                return atoi( code );
            }

            idx = 0;
        }
    }
    while( 1 );
}
예제 #11
0
static ssize_t tls_write(esp_tls_t *tls, const char *data, size_t datalen)
{
    ssize_t ret = mbedtls_ssl_write(&tls->ssl, (unsigned char*) data, datalen);
    if (ret < 0) {
        if (ret != MBEDTLS_ERR_SSL_WANT_READ  && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
            ESP_LOGE(TAG, "write error :%d:", ret);
        }
    }
    return ret;
}
int coap_security_handler_send_message(coap_security_t *sec, unsigned char *message, size_t len){
    int ret=-1;

    if( sec ){
        do ret = mbedtls_ssl_write( &sec->_ssl, (unsigned char *) message, len );
        while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
               ret == MBEDTLS_ERR_SSL_WANT_WRITE );
    }

    return ret; //bytes written
}
예제 #13
0
파일: ssl.c 프로젝트: jonasmalacofilho/neko
static value ssl_send_char( value ssl, value v ) {
	unsigned char cc;
	int c;
	val_check_kind(ssl,k_ssl);
	val_check(v,int);
	c = val_int(v);
	if( c < 0 || c > 255 )
		neko_error();
	cc = (unsigned char) c;
	mbedtls_ssl_write( val_ssl(ssl), &cc, 1 );
	return val_true;
}
예제 #14
0
/** Write data to a TLS connection. Calls into mbedTLS, which in turn calls into
 * @ref altcp_mbedtls_bio_send() to send the encrypted data
 */
static err_t
altcp_mbedtls_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags)
{
  int ret;
  altcp_mbedtls_state_t *state;

  LWIP_UNUSED_ARG(apiflags);

  if (conn == NULL) {
    return ERR_VAL;
  }

  state = (altcp_mbedtls_state_t *)conn->state;
  if (state == NULL) {
    /* @todo: which error? */
    return ERR_CLSD;
  }
  if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
    /* @todo: which error? */
    return ERR_VAL;
  }

  /* HACK: if thre is something left to send, try to flush it and only
     allow sending more if this succeeded (this is a hack because neither
     returning 0 nor MBEDTLS_ERR_SSL_WANT_WRITE worked for me) */
  if (state->ssl_context.out_left) {
    mbedtls_ssl_flush_output(&state->ssl_context);
    if (state->ssl_context.out_left) {
      return ERR_MEM;
    }
  }
  ret = mbedtls_ssl_write(&state->ssl_context, (const unsigned char *)dataptr, len);
  /* try to send data... */
  altcp_output(conn->inner_conn);
  if (ret >= 0) {
    if (ret == len) {
      state->flags |= ALTCP_MBEDTLS_FLAGS_APPLDATA_SENT;
      return ERR_OK;
    } else {
      /* @todo/@fixme: assumption: either everything sent or error */
      LWIP_ASSERT("ret <= 0", 0);
      return ERR_MEM;
    }
  } else {
    if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
      /* @todo: convert error to err_t */
      return ERR_MEM;
    }
    LWIP_ASSERT("unhandled error", 0);
    return ERR_VAL;
  }
}
예제 #15
0
static int send_response(struct zoap_packet *request, u8_t response_code)
{
	struct net_pkt *pkt;
	struct net_buf *frag;
	struct zoap_packet response;
	u8_t code, type;
	u16_t id;
	int r;

	code = zoap_header_get_code(request);
	type = zoap_header_get_type(request);
	id = zoap_header_get_id(request);

	printk("*******\n");
	printk("type: %u code %u id %u\n", type, code, id);
	printk("*******\n");

	pkt = net_pkt_get_reserve(&zoap_pkt_slab, 0, K_NO_WAIT);
	if (!pkt) {
		return -ENOMEM;
	}

	frag = net_buf_alloc(&zoap_data_pool, K_NO_WAIT);
	if (!frag) {
		return -ENOMEM;
	}

	net_pkt_frag_add(pkt, frag);

	r = zoap_packet_init(&response, pkt);
	if (r < 0) {
		return -EINVAL;
	}

	zoap_header_set_version(&response, 1);
	zoap_header_set_type(&response, ZOAP_TYPE_ACK);
	zoap_header_set_code(&response, response_code);
	zoap_header_set_id(&response, id);

	do {
		r = mbedtls_ssl_write(curr_ctx, frag->data, frag->len);
	} while (r == MBEDTLS_ERR_SSL_WANT_READ
		 || r == MBEDTLS_ERR_SSL_WANT_WRITE);

	if (r >= 0) {
		r = 0;
	}

	net_pkt_unref(pkt);

	return r;
}
예제 #16
0
/* Send data via TLS connection
 */
int tls_send(mbedtls_ssl_context *context, const char *buffer, unsigned int length) {
	int result;

	do {
		result = mbedtls_ssl_write(context, (unsigned char*)buffer, length);
	} while (result == MBEDTLS_ERR_SSL_WANT_WRITE);

	if (result < 0) {
		return -1;
	}

	return result;
}
예제 #17
0
int SSLContext::write(State & state, SSLContextData * ssl_context_data) {
    Stack * stack = state.stack;
    if (stack->is<LUA_TSTRING>(1)) {
        const std::string buffer = stack->toLString(1);
        int result = mbedtls_ssl_write(ssl_context_data->context, reinterpret_cast<const unsigned char *>(buffer.c_str()), buffer.length());

        stack->push<int>(result);
        return 1;
    }
    else {
        return 0;
    }
}
예제 #18
0
파일: serve.c 프로젝트: funnydog/webserve
static int tls_client_write(struct client *c, const void *data, size_t len)
{
	const uint8_t *buf = data;
	while (len > 0) {
		ssize_t r = mbedtls_ssl_write(&c->ssl, buf, len);
		if (r <= 0)
			return -1;

		buf += r;
		len -= r;
	}

	return 0;
}
예제 #19
0
int dslink_socket_write(Socket *sock, char *buf, size_t len) {
    int r;
    if (sock->secure) {
        r = mbedtls_ssl_write(((SslSocket *) sock)->ssl,
                              (unsigned char *) buf, len);
    } else {
        r = mbedtls_net_send(sock->socket_fd, (unsigned char *) buf, len);
    }
    if (r < 0) {
        errno = r;
        return DSLINK_SOCK_WRITE_ERR;
    }
    return r;
}
예제 #20
0
int openssl_write(struct connection *conn)
{
	int n = mbedtls_ssl_write(conn->ssl, (unsigned char *)conn->curp, conn->length);
	if (n < 0)
		switch (n) {
		case MBEDTLS_ERR_SSL_WANT_READ:
		case MBEDTLS_ERR_SSL_WANT_WRITE:
			return -EAGAIN;
		default:
			printf("Not read or write\n");
			break;
		}

	return n;
}
예제 #21
0
파일: ssl.c 프로젝트: dancahill/nsp
int _ssl_write(nsp_state *N, TCP_SOCKET *sock, const void *buf, int max)
{
#define __FN__ __FILE__ ":_ssl_write()"
#if defined HAVE_OPENSSL
	return SSL_write(sock->ssl, buf, max);
#elif defined HAVE_MBEDTLS
	int rc;

	do {
		rc = mbedtls_ssl_write(&sock->ssl, (void *)buf, max);
	} while (rc == MBEDTLS_ERR_SSL_WANT_READ || rc == MBEDTLS_ERR_SSL_WANT_WRITE);
	return rc;
#endif
#undef __FN__
}
int iot_tls_write(Network *pNetwork, unsigned char *pMsg, int len, int timeout_ms) {

	int written;
	int frags;

	for (written = 0, frags = 0; written < len; written += ret, frags++) {
		while ((ret = mbedtls_ssl_write(&ssl, pMsg + written, len - written)) <= 0) {
			if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
				ERROR(" failed\n  ! mbedtls_ssl_write returned -0x%x\n\n", -ret);
				return ret;
			}
		}
	}
	return written;
}
예제 #23
0
/* Send buffer via TLS
 */
int tls_send_buffer(mbedtls_ssl_context *context, const char *buffer, int size) {
	int bytes_written, total_written = 0;

	if (size <= 0) {
		return 0;
	} else while (total_written < size) {
		if ((bytes_written = mbedtls_ssl_write(context, (unsigned char*)buffer + total_written, size - total_written)) > 0) {
			total_written += bytes_written;
		} else if (bytes_written != MBEDTLS_ERR_SSL_WANT_WRITE) {
			return -1;
		}
	}

	return total_written;
}
예제 #24
0
int ssl_socket_send_all_blocking(void *state_data, const void *data_, size_t size, bool no_signal)
{
   struct ssl_state *state = (struct ssl_state*)state_data;
   const uint8_t *data = (const uint8_t*)data_;
   int ret;

   mbedtls_net_set_block(&state->net_ctx);

   while ((ret = mbedtls_ssl_write(&state->ctx, data, size)) <= 0)
   {
      if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
         return false;
   }

   return true;
}
예제 #25
0
static int write_ssl_data( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
{
    int ret;

    mbedtls_printf("\n%s", buf);
    while( len && ( ret = mbedtls_ssl_write( ssl, buf, len ) ) <= 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
            return -1;
        }
    }

    return( 0 );
}
예제 #26
0
ssize_t ssl_socket_send_all_nonblocking(void *state_data, const void *data_, size_t size, bool no_signal)
{
   struct ssl_state *state = (struct ssl_state*)state_data;
   const uint8_t *data = (const uint8_t*)data_;
   ssize_t sent = size;
   int ret;

   mbedtls_net_set_nonblock(&state->net_ctx);

   ret = mbedtls_ssl_write(&state->ctx, data, size);

   if (ret <= 0)
      return -1;

   return sent;
}
예제 #27
0
파일: clax.c 프로젝트: clarive/clax
int clax_send_ssl(void *ctx, const unsigned char *buf, size_t len)
{
    int ret;
    mbedtls_ssl_context *ssl = ctx;

    while ((ret = mbedtls_ssl_write(ssl, buf, len)) <= 0) {
        if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
            clax_log("failed\n  ! mbedtls_ssl_write returned %d", ret);
            return ret;
        }
    }

    /*clax_log("send (ssl)=%d from %d", ret, len);*/

    return ret;
}
예제 #28
0
static ssize_t mbed_send(struct connectdata *conn, int sockindex,
                         const void *mem, size_t len,
                         CURLcode *curlcode)
{
  int ret = -1;

  ret = mbedtls_ssl_write(&conn->ssl[sockindex].ssl,
                          (unsigned char *)mem, len);

  if(ret < 0) {
    *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ?
      CURLE_AGAIN : CURLE_SEND_ERROR;
    ret = -1;
  }

  return ret;
}
예제 #29
0
파일: ssl_pm.c 프로젝트: kubecz3k/godot
/*
 * This returns -1, or the length sent.
 * If -1, then you need to find out if the error was
 * fatal or recoverable using SSL_get_error()
 */
int ssl_pm_send(SSL *ssl, const void *buffer, int len)
{
    int ret;
    struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;

    ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len);
    /*
     * We can get a positive number, which may be less than len... that
     * much was sent successfully and you can call again to send more.
     *
     * We can get a negative mbedtls error code... if WANT_WRITE or WANT_READ,
     * it's nonfatal and means it should be retried as-is.  If something else,
     * it's fatal actually.
     *
     * If this function returns something other than a positive value or
     * MBEDTLS_ERR_SSL_WANT_READ/WRITE, the ssl context becomes unusable, and
     * you should either free it or call mbedtls_ssl_session_reset() on it
     * before re-using it for a new connection; the current connection must
     * be closed.
     *
     * When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, it must be
     * called later with the same arguments, until it returns a positive value.
     */

    if (ret < 0) {
	    SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_write() return -0x%x", -ret);
	switch (ret) {
	case MBEDTLS_ERR_NET_CONN_RESET:
		ssl->err = SSL_ERROR_SYSCALL;
		break;
	case MBEDTLS_ERR_SSL_WANT_WRITE:
		ssl->err = SSL_ERROR_WANT_WRITE;
		break;
	case MBEDTLS_ERR_SSL_WANT_READ:
		ssl->err = SSL_ERROR_WANT_READ;
		break;
	default:
		break;
	}

	ret = -1;
    }

    return ret;
}
예제 #30
0
STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
    mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);

    int ret = mbedtls_ssl_write(&o->ssl, buf, size);
    if (ret >= 0) {
        return ret;
    }
    if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
        ret = MP_EWOULDBLOCK;
    } else if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
        // If handshake is not finished, write attempt may end up in protocol
        // wanting to read next handshake message. The same may happen with
        // renegotation.
        ret = MP_EWOULDBLOCK;
    }
    *errcode = ret;
    return MP_STREAM_ERROR;
}