* Application layered TCP/TLS connection API (to be used from TCPIP thread)
*
* This file provides a TLS layer using mbedTLS
- *
+ *
* This version is currently compatible with the 2.x.x branch (current LTS).
*/
/* @todo: which includes are really needed? */
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
-#include "mbedtls/certs.h"
#include "mbedtls/x509.h"
#include "mbedtls/ssl.h"
#include "mbedtls/net_sockets.h"
#include "mbedtls/ssl_cache.h"
#include "mbedtls/ssl_ticket.h"
-#include "mbedtls/ssl_internal.h" /* to call mbedtls_flush_output after ERR_MEM */
-
#include <string.h>
#ifndef ALTCP_MBEDTLS_ENTROPY_PTR
static err_t altcp_mbedtls_handle_rx_appldata(struct altcp_pcb *conn, altcp_mbedtls_state_t *state);
static int altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size);
+static void
+altcp_mbedtls_flush_output(altcp_mbedtls_state_t *state)
+{
+ if (state->ssl_context.MBEDTLS_PRIVATE(out_left) != 0) {
+ int flushed = mbedtls_ssl_send_alert_message(&state->ssl_context, 0, 0);
+ if (flushed) {
+ LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_send_alert_message failed: %d\n", flushed));
+ }
+ }
+}
/* callback functions from inner/lower connection: */
LWIP_ASSERT("state", state != NULL);
LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
/* calculate TLS overhead part to not send it to application */
- overhead = state->overhead_bytes_adjust + state->ssl_context.out_left;
+ overhead = state->overhead_bytes_adjust + state->ssl_context.MBEDTLS_PRIVATE(out_left);
if ((unsigned)overhead > len) {
overhead = len;
}
/* remove ACKed bytes from overhead adjust counter */
state->overhead_bytes_adjust -= len;
/* try to send more if we failed before (may increase overhead adjust counter) */
- mbedtls_ssl_flush_output(&state->ssl_context);
+ altcp_mbedtls_flush_output(state);
/* remove calculated overhead from ACKed bytes len */
app_len = len - (u16_t)overhead;
/* update application write counter and inform application */
if (conn->state) {
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
/* try to send more if we failed before */
- mbedtls_ssl_flush_output(&state->ssl_context);
+ altcp_mbedtls_flush_output(state);
if (altcp_mbedtls_handle_rx_appldata(conn, state) == ERR_ABRT) {
return ERR_ABRT;
}
if (session && conn && conn->state) {
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
int ret = -1;
- if (session->data.start)
+ if (session->data.MBEDTLS_PRIVATE(start))
ret = mbedtls_ssl_set_session(&state->ssl_context, &session->data);
return ret < 0 ? ERR_VAL : ERR_OK;
}
struct altcp_tls_config *conf;
mbedtls_x509_crt *mem;
- if (TCP_WND < MBEDTLS_SSL_MAX_CONTENT_LEN) {
+ if (TCP_WND < MBEDTLS_SSL_IN_CONTENT_LEN || TCP_WND < MBEDTLS_SSL_OUT_CONTENT_LEN) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG|LWIP_DBG_LEVEL_SERIOUS,
("altcp_tls: TCP_WND is smaller than the RX decrypion buffer, connection RX might stall!\n"));
}
return ERR_VAL;
}
- ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len);
+ ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
mbedtls_x509_crt_free(srvcert);
}
mbedtls_pk_init(conf->pkey);
- ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len);
+ ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x\n", ret, -1*ret));
altcp_tls_free_config(conf);
size_t ret;
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
/* @todo: adjust ssl_added to real value related to negotiated cipher */
- size_t max_frag_len = mbedtls_ssl_get_max_frag_len(&state->ssl_context);
+ size_t max_frag_len = mbedtls_ssl_get_max_in_record_payload(&state->ssl_context);
max_len = LWIP_MIN(max_frag_len, max_len);
#endif
/* Adjust sndbuf of inner_conn with what added by SSL */
/* HACK: if there 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) {
+ if (state->ssl_context.MBEDTLS_PRIVATE(out_left)) {
+ altcp_mbedtls_flush_output(state);
+ if (state->ssl_context.MBEDTLS_PRIVATE(out_left)) {
return ERR_MEM;
}
}
while (size_left) {
u16_t write_len = (u16_t)LWIP_MIN(size_left, 0xFFFF);
err_t err = altcp_write(conn->inner_conn, (const void *)dataptr, write_len, apiflags);
+ /* try to send data... */
+ altcp_output(conn->inner_conn);
if (err == ERR_OK) {
written += write_len;
size_left -= write_len;