|
|
@@ -119,21 +119,18 @@ static int tls_mbedtls_read(void *ctx, unsigned char *buf, size_t len)
|
|
|
struct tls_connection *conn = (struct tls_connection *)ctx;
|
|
|
struct tls_data *data = &conn->tls_io_data;
|
|
|
struct wpabuf *local_buf;
|
|
|
- size_t data_len = len;
|
|
|
|
|
|
- if (data->in_data == NULL) {
|
|
|
+ if (data->in_data == NULL || len > wpabuf_len(data->in_data)) {
|
|
|
+ /* We don't have suffient buffer available for read */
|
|
|
+ wpa_printf(MSG_INFO, "len=%zu not available in input", len);
|
|
|
return MBEDTLS_ERR_SSL_WANT_READ;
|
|
|
}
|
|
|
|
|
|
- if (len > wpabuf_len(data->in_data)) {
|
|
|
- wpa_printf(MSG_ERROR, "don't have suffient data\n");
|
|
|
- data_len = wpabuf_len(data->in_data);
|
|
|
- }
|
|
|
-
|
|
|
- os_memcpy(buf, wpabuf_head(data->in_data), data_len);
|
|
|
+ os_memcpy(buf, wpabuf_head(data->in_data), len);
|
|
|
/* adjust buffer */
|
|
|
if (len < wpabuf_len(data->in_data)) {
|
|
|
- local_buf = wpabuf_alloc_copy(wpabuf_head(data->in_data) + len,
|
|
|
+ /* TODO optimize this operation */
|
|
|
+ local_buf = wpabuf_alloc_copy(wpabuf_mhead_u8(data->in_data) + len,
|
|
|
wpabuf_len(data->in_data) - len);
|
|
|
wpabuf_free(data->in_data);
|
|
|
data->in_data = local_buf;
|
|
|
@@ -142,7 +139,7 @@ static int tls_mbedtls_read(void *ctx, unsigned char *buf, size_t len)
|
|
|
data->in_data = NULL;
|
|
|
}
|
|
|
|
|
|
- return data_len;
|
|
|
+ return len;
|
|
|
}
|
|
|
|
|
|
static int set_pki_context(tls_context_t *tls, const struct tls_connection_params *cfg)
|
|
|
@@ -558,6 +555,7 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx,
|
|
|
{
|
|
|
tls_context_t *tls = conn->tls;
|
|
|
int ret = 0;
|
|
|
+ struct wpabuf *resp;
|
|
|
|
|
|
/* data freed by sender */
|
|
|
conn->tls_io_data.out_data = NULL;
|
|
|
@@ -591,7 +589,9 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx,
|
|
|
}
|
|
|
|
|
|
end:
|
|
|
- return conn->tls_io_data.out_data;
|
|
|
+ resp = conn->tls_io_data.out_data;
|
|
|
+ conn->tls_io_data.out_data = NULL;
|
|
|
+ return resp;
|
|
|
}
|
|
|
|
|
|
struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
|
|
|
@@ -608,10 +608,12 @@ struct wpabuf * tls_connection_encrypt(void *tls_ctx,
|
|
|
struct tls_connection *conn,
|
|
|
const struct wpabuf *in_data)
|
|
|
{
|
|
|
+ struct wpabuf *resp;
|
|
|
+ size_t ret;
|
|
|
+
|
|
|
/* Reset dangling pointer */
|
|
|
conn->tls_io_data.out_data = NULL;
|
|
|
-
|
|
|
- ssize_t ret = mbedtls_ssl_write(&conn->tls->ssl,
|
|
|
+ ret = mbedtls_ssl_write(&conn->tls->ssl,
|
|
|
(unsigned char*) wpabuf_head(in_data), wpabuf_len(in_data));
|
|
|
|
|
|
if (ret < wpabuf_len(in_data)) {
|
|
|
@@ -619,27 +621,50 @@ struct wpabuf * tls_connection_encrypt(void *tls_ctx,
|
|
|
__func__, __LINE__);
|
|
|
}
|
|
|
|
|
|
- return conn->tls_io_data.out_data;
|
|
|
+ resp = conn->tls_io_data.out_data;
|
|
|
+ conn->tls_io_data.out_data = NULL;
|
|
|
+ return resp;
|
|
|
}
|
|
|
|
|
|
|
|
|
-struct wpabuf * tls_connection_decrypt(void *tls_ctx,
|
|
|
- struct tls_connection *conn,
|
|
|
- const struct wpabuf *in_data)
|
|
|
+struct wpabuf *tls_connection_decrypt(void *tls_ctx,
|
|
|
+ struct tls_connection *conn,
|
|
|
+ const struct wpabuf *in_data)
|
|
|
{
|
|
|
- unsigned char buf[1200];
|
|
|
+#define MAX_PHASE2_BUFFER 1536
|
|
|
+ struct wpabuf *out = NULL;
|
|
|
int ret;
|
|
|
+ unsigned char *buf = os_malloc(MAX_PHASE2_BUFFER);
|
|
|
+
|
|
|
+ if (!buf) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ /* Reset dangling output buffer before setting data, data was freed by caller */
|
|
|
+ conn->tls_io_data.out_data = NULL;
|
|
|
+
|
|
|
conn->tls_io_data.in_data = wpabuf_dup(in_data);
|
|
|
- ret = mbedtls_ssl_read(&conn->tls->ssl, buf, 1200);
|
|
|
+
|
|
|
+ if (!conn->tls_io_data.in_data) {
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ ret = mbedtls_ssl_read(&conn->tls->ssl, buf, MAX_PHASE2_BUFFER);
|
|
|
if (ret < 0) {
|
|
|
- wpa_printf(MSG_ERROR, "%s:%d, not able to write whole data",
|
|
|
+ wpa_printf(MSG_ERROR, "%s:%d, not able to read data",
|
|
|
__func__, __LINE__);
|
|
|
- return NULL;
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ out = wpabuf_alloc_copy(buf, ret);
|
|
|
+cleanup:
|
|
|
+ /* there may be some error written in output buffer */
|
|
|
+ if (conn->tls_io_data.out_data) {
|
|
|
+ os_free(conn->tls_io_data.out_data);
|
|
|
+ conn->tls_io_data.out_data = NULL;
|
|
|
}
|
|
|
|
|
|
- struct wpabuf *out = wpabuf_alloc_copy(buf, ret);
|
|
|
+ os_free(buf);
|
|
|
|
|
|
return out;
|
|
|
+#undef MAX_PHASE2_BUFFER
|
|
|
}
|
|
|
|
|
|
|