1 /**
2 * @file
3 * Application layered TCP/TLS connection API (to be used from TCPIP thread)
4 *
5 * This file provides a TLS layer using mbedTLS
6 *
7 * This version is currently compatible with the 2.x.x branch (current LTS).
8 */
9
10 /*
11 * Copyright (c) 2017 Simon Goldschmidt
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright notice,
18 * this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright notice,
20 * this list of conditions and the following disclaimer in the documentation
21 * and/or other materials provided with the distribution.
22 * 3. The name of the author may not be used to endorse or promote products
23 * derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
28 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 * OF SUCH DAMAGE.
35 *
36 * This file is part of the lwIP TCP/IP stack.
37 *
38 * Author: Simon Goldschmidt <goldsimon@gmx.de>
39 *
40 * Watch out:
41 * - 'sent' is always called with len==0 to the upper layer. This is because keeping
42 * track of the ratio of application data and TLS overhead would be too much.
43 *
44 * Mandatory security-related configuration:
45 * - ensure to add at least one strong entropy source to your mbedtls port (implement
46 * mbedtls_platform_entropy_poll or mbedtls_hardware_poll providing strong entropy)
47 * - define ALTCP_MBEDTLS_ENTROPY_PTR and ALTCP_MBEDTLS_ENTROPY_LEN to something providing
48 * GOOD custom entropy
49 *
50 * Missing things / @todo:
51 * - some unhandled/untested things might be caught by LWIP_ASSERTs...
52 */
53
54 #include "lwip/opt.h"
55 #include "lwip/sys.h"
56
57 #if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
58
59 #include "lwip/apps/altcp_tls_mbedtls_opts.h"
60
61 #if LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS
62
63 #include "lwip/altcp.h"
64 #include "lwip/altcp_tls.h"
65 #include "lwip/priv/altcp_priv.h"
66
67 #include "altcp_tls_mbedtls_structs.h"
68 #include "altcp_tls_mbedtls_mem.h"
69
70 /* @todo: which includes are really needed? */
71 #include "mbedtls/entropy.h"
72 #include "mbedtls/ctr_drbg.h"
73 #include "mbedtls/certs.h"
74 #include "mbedtls/x509.h"
75 #include "mbedtls/ssl.h"
76 #include "mbedtls/net_sockets.h"
77 #include "mbedtls/error.h"
78 #include "mbedtls/debug.h"
79 #include "mbedtls/platform.h"
80 #include "mbedtls/memory_buffer_alloc.h"
81 #include "mbedtls/ssl_cache.h"
82 #include "mbedtls/ssl_ticket.h"
83
84 #include "mbedtls/ssl_internal.h" /* to call mbedtls_flush_output after ERR_MEM */
85
86 #include <string.h>
87
88 #ifndef ALTCP_MBEDTLS_ENTROPY_PTR
89 #define ALTCP_MBEDTLS_ENTROPY_PTR NULL
90 #endif
91 #ifndef ALTCP_MBEDTLS_ENTROPY_LEN
92 #define ALTCP_MBEDTLS_ENTROPY_LEN 0
93 #endif
94 #ifndef ALTCP_MBEDTLS_RNG_FN
95 #define ALTCP_MBEDTLS_RNG_FN mbedtls_entropy_func
96 #endif
97
98 /* Variable prototype, the actual declaration is at the end of this file
99 since it contains pointers to static functions declared here */
100 extern const struct altcp_functions altcp_mbedtls_functions;
101
102 /** Our global mbedTLS configuration (server-specific, not connection-specific) */
103 struct altcp_tls_config {
104 mbedtls_ssl_config conf;
105 mbedtls_x509_crt *cert;
106 mbedtls_pk_context *pkey;
107 u8_t cert_count;
108 u8_t cert_max;
109 u8_t pkey_count;
110 u8_t pkey_max;
111 mbedtls_x509_crt *ca;
112 #if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
113 /** Inter-connection cache for fast connection startup */
114 struct mbedtls_ssl_cache_context cache;
115 #endif
116 #if defined(MBEDTLS_SSL_SESSION_TICKETS) && ALTCP_MBEDTLS_USE_SESSION_TICKETS
117 mbedtls_ssl_ticket_context ticket_ctx;
118 #endif
119 };
120
121 /** Entropy and random generator are shared by all mbedTLS configuration */
122 struct altcp_tls_entropy_rng {
123 mbedtls_entropy_context entropy;
124 mbedtls_ctr_drbg_context ctr_drbg;
125 int ref;
126 };
127 static struct altcp_tls_entropy_rng *altcp_tls_entropy_rng;
128
129 static err_t altcp_mbedtls_lower_recv(void *arg, struct altcp_pcb *inner_conn, struct pbuf *p, err_t err);
130 static err_t altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn);
131 static err_t altcp_mbedtls_lower_recv_process(struct altcp_pcb *conn, altcp_mbedtls_state_t *state);
132 static err_t altcp_mbedtls_handle_rx_appldata(struct altcp_pcb *conn, altcp_mbedtls_state_t *state);
133 static int altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size);
134
135
136 static void
altcp_mbedtls_flush_output(altcp_mbedtls_state_t * state)137 altcp_mbedtls_flush_output(altcp_mbedtls_state_t* state)
138 {
139 int flushed = mbedtls_ssl_flush_output(&state->ssl_context);
140 if (flushed) {
141 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_flush_output failed: %d\n", flushed));
142 }
143 }
144
145 /* callback functions from inner/lower connection: */
146
147 /** Accept callback from lower connection (i.e. TCP)
148 * Allocate one of our structures, assign it to the new connection's 'state' and
149 * call the new connection's 'accepted' callback. If that succeeds, we wait
150 * to receive connection setup handshake bytes from the client.
151 */
152 static err_t
altcp_mbedtls_lower_accept(void * arg,struct altcp_pcb * accepted_conn,err_t err)153 altcp_mbedtls_lower_accept(void *arg, struct altcp_pcb *accepted_conn, err_t err)
154 {
155 struct altcp_pcb *listen_conn = (struct altcp_pcb *)arg;
156 if (listen_conn && listen_conn->state && listen_conn->accept) {
157 err_t setup_err;
158 altcp_mbedtls_state_t *listen_state = (altcp_mbedtls_state_t *)listen_conn->state;
159 /* create a new altcp_conn to pass to the next 'accept' callback */
160 struct altcp_pcb *new_conn = altcp_alloc();
161 if (new_conn == NULL) {
162 return ERR_MEM;
163 }
164 setup_err = altcp_mbedtls_setup(listen_state->conf, new_conn, accepted_conn);
165 if (setup_err != ERR_OK) {
166 altcp_free(new_conn);
167 return setup_err;
168 }
169 return listen_conn->accept(listen_conn->arg, new_conn, err);
170 }
171 return ERR_ARG;
172 }
173
174 /** Connected callback from lower connection (i.e. TCP).
175 * Not really implemented/tested yet...
176 */
177 static err_t
altcp_mbedtls_lower_connected(void * arg,struct altcp_pcb * inner_conn,err_t err)178 altcp_mbedtls_lower_connected(void *arg, struct altcp_pcb *inner_conn, err_t err)
179 {
180 struct altcp_pcb *conn = (struct altcp_pcb *)arg;
181 LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */
182 if (conn && conn->state) {
183 altcp_mbedtls_state_t *state;
184 LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
185 /* upper connected is called when handshake is done */
186 if (err != ERR_OK) {
187 if (conn->connected) {
188 return conn->connected(conn->arg, conn, err);
189 }
190 }
191 state = (altcp_mbedtls_state_t *)conn->state;
192 /* ensure overhead value is valid before first write */
193 state->overhead_bytes_adjust = 0;
194 return altcp_mbedtls_lower_recv_process(conn, state);
195 }
196 return ERR_VAL;
197 }
198
199 /* Call recved for possibly more than an u16_t */
200 static void
altcp_mbedtls_lower_recved(struct altcp_pcb * inner_conn,int recvd_cnt)201 altcp_mbedtls_lower_recved(struct altcp_pcb *inner_conn, int recvd_cnt)
202 {
203 while (recvd_cnt > 0) {
204 u16_t recvd_part = (u16_t)LWIP_MIN(recvd_cnt, 0xFFFF);
205 altcp_recved(inner_conn, recvd_part);
206 recvd_cnt -= recvd_part;
207 }
208 }
209
210 /** Recv callback from lower connection (i.e. TCP)
211 * This one mainly differs between connection setup/handshake (data is fed into mbedTLS only)
212 * and application phase (data is decoded by mbedTLS and passed on to the application).
213 */
214 static err_t
altcp_mbedtls_lower_recv(void * arg,struct altcp_pcb * inner_conn,struct pbuf * p,err_t err)215 altcp_mbedtls_lower_recv(void *arg, struct altcp_pcb *inner_conn, struct pbuf *p, err_t err)
216 {
217 altcp_mbedtls_state_t *state;
218 struct altcp_pcb *conn = (struct altcp_pcb *)arg;
219
220 LWIP_ASSERT("no err expected", err == ERR_OK);
221 LWIP_UNUSED_ARG(err);
222
223 if (!conn) {
224 /* no connection given as arg? should not happen, but prevent pbuf/conn leaks */
225 if (p != NULL) {
226 pbuf_free(p);
227 }
228 altcp_close(inner_conn);
229 return ERR_CLSD;
230 }
231 state = (altcp_mbedtls_state_t *)conn->state;
232 LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
233 if (!state) {
234 /* already closed */
235 if (p != NULL) {
236 pbuf_free(p);
237 }
238 altcp_close(inner_conn);
239 return ERR_CLSD;
240 }
241
242 /* handle NULL pbuf (inner connection closed) */
243 if (p == NULL) {
244 /* remote host sent FIN, remember this (SSL state is destroyed
245 when both sides are closed only!) */
246 if ((state->flags & (ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE | ALTCP_MBEDTLS_FLAGS_UPPER_CALLED)) ==
247 (ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE | ALTCP_MBEDTLS_FLAGS_UPPER_CALLED)) {
248 /* need to notify upper layer (e.g. 'accept' called or 'connect' succeeded) */
249 if ((state->rx != NULL) || (state->rx_app != NULL)) {
250 state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED;
251 /* this is a normal close (FIN) but we have unprocessed data, so delay the FIN */
252 altcp_mbedtls_handle_rx_appldata(conn, state);
253 return ERR_OK;
254 }
255 state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSED;
256 if (conn->recv) {
257 return conn->recv(conn->arg, conn, NULL, ERR_OK);
258 }
259 } else {
260 /* before connection setup is done: call 'err' */
261 if (conn->err) {
262 conn->err(conn->arg, ERR_ABRT);
263 }
264 altcp_close(conn);
265 }
266 return ERR_OK;
267 }
268
269 /* If we come here, the connection is in good state (handshake phase or application data phase).
270 Queue up the pbuf for processing as handshake data or application data. */
271 if (state->rx == NULL) {
272 state->rx = p;
273 } else {
274 LWIP_ASSERT("rx pbuf overflow", (int)p->tot_len + (int)p->len <= 0xFFFF);
275 pbuf_cat(state->rx, p);
276 }
277 return altcp_mbedtls_lower_recv_process(conn, state);
278 }
279
280 static err_t
altcp_mbedtls_lower_recv_process(struct altcp_pcb * conn,altcp_mbedtls_state_t * state)281 altcp_mbedtls_lower_recv_process(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
282 {
283 if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
284 /* handle connection setup (handshake not done) */
285 int ret = mbedtls_ssl_handshake(&state->ssl_context);
286 /* try to send data... */
287 altcp_output(conn->inner_conn);
288 if (state->bio_bytes_read) {
289 /* acknowledge all bytes read */
290 altcp_mbedtls_lower_recved(conn->inner_conn, state->bio_bytes_read);
291 state->bio_bytes_read = 0;
292 }
293
294 if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
295 /* handshake not done, wait for more recv calls */
296 LWIP_ASSERT("in this state, the rx chain should be empty", state->rx == NULL);
297 return ERR_OK;
298 }
299 if (ret != 0) {
300 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_handshake failed: %d\n", ret));
301 /* handshake failed, connection has to be closed */
302 if (conn->err) {
303 conn->err(conn->arg, ERR_CLSD);
304 }
305
306 if (altcp_close(conn) != ERR_OK) {
307 altcp_abort(conn);
308 }
309 return ERR_OK;
310 }
311 /* If we come here, handshake succeeded. */
312 LWIP_ASSERT("state", state->bio_bytes_read == 0);
313 LWIP_ASSERT("state", state->bio_bytes_appl == 0);
314 state->flags |= ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE;
315 /* issue "connect" callback" to upper connection (this can only happen for active open) */
316 if (conn->connected) {
317 err_t err;
318 err = conn->connected(conn->arg, conn, ERR_OK);
319 if (err != ERR_OK) {
320 return err;
321 }
322 }
323 if (state->rx == NULL) {
324 return ERR_OK;
325 }
326 }
327 /* handle application data */
328 return altcp_mbedtls_handle_rx_appldata(conn, state);
329 }
330
331 /* Pass queued decoded rx data to application */
332 static err_t
altcp_mbedtls_pass_rx_data(struct altcp_pcb * conn,altcp_mbedtls_state_t * state)333 altcp_mbedtls_pass_rx_data(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
334 {
335 err_t err;
336 struct pbuf *buf;
337 LWIP_ASSERT("conn != NULL", conn != NULL);
338 LWIP_ASSERT("state != NULL", state != NULL);
339 buf = state->rx_app;
340 if (buf) {
341 state->rx_app = NULL;
342 if (conn->recv) {
343 u16_t tot_len = buf->tot_len;
344 /* this needs to be increased first because the 'recved' call may come nested */
345 state->rx_passed_unrecved += tot_len;
346 state->flags |= ALTCP_MBEDTLS_FLAGS_UPPER_CALLED;
347 err = conn->recv(conn->arg, conn, buf, ERR_OK);
348 if (err != ERR_OK) {
349 if (err == ERR_ABRT) {
350 return ERR_ABRT;
351 }
352 /* not received, leave the pbuf(s) queued (and decrease 'unrecved' again) */
353 LWIP_ASSERT("state == conn->state", state == conn->state);
354 state->rx_app = buf;
355 state->rx_passed_unrecved -= tot_len;
356 LWIP_ASSERT("state->rx_passed_unrecved >= 0", state->rx_passed_unrecved >= 0);
357 if (state->rx_passed_unrecved < 0) {
358 state->rx_passed_unrecved = 0;
359 }
360 return err;
361 }
362 } else {
363 pbuf_free(buf);
364 }
365 } else if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) ==
366 ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) {
367 state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSED;
368 if (conn->recv) {
369 return conn->recv(conn->arg, conn, NULL, ERR_OK);
370 }
371 }
372
373 /* application may have close the connection */
374 if (conn->state != state) {
375 /* return error code to ensure altcp_mbedtls_handle_rx_appldata() exits the loop */
376 return ERR_ARG;
377 }
378 return ERR_OK;
379 }
380
381 /* Helper function that processes rx application data stored in rx pbuf chain */
382 static err_t
altcp_mbedtls_handle_rx_appldata(struct altcp_pcb * conn,altcp_mbedtls_state_t * state)383 altcp_mbedtls_handle_rx_appldata(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
384 {
385 int ret;
386 LWIP_ASSERT("state != NULL", state != NULL);
387 if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
388 /* handshake not done yet */
389 return ERR_VAL;
390 }
391 do {
392 /* allocate a full-sized unchained PBUF_POOL: this is for RX! */
393 struct pbuf *buf = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL);
394 if (buf == NULL) {
395 /* We're short on pbufs, try again later from 'poll' or 'recv' callbacks.
396 @todo: close on excessive allocation failures or leave this up to upper conn? */
397 return ERR_OK;
398 }
399
400 /* decrypt application data, this pulls encrypted RX data off state->rx pbuf chain */
401 ret = mbedtls_ssl_read(&state->ssl_context, (unsigned char *)buf->payload, PBUF_POOL_BUFSIZE);
402 if (ret < 0) {
403 if (ret == MBEDTLS_ERR_SSL_CLIENT_RECONNECT) {
404 /* client is initiating a new connection using the same source port -> close connection or make handshake */
405 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("new connection on same source port\n"));
406 LWIP_ASSERT("TODO: new connection on same source port, close this connection", 0);
407 } else if ((ret != MBEDTLS_ERR_SSL_WANT_READ) && (ret != MBEDTLS_ERR_SSL_WANT_WRITE)) {
408 if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
409 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("connection was closed gracefully\n"));
410 } else if (ret == MBEDTLS_ERR_NET_CONN_RESET) {
411 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("connection was reset by peer\n"));
412 }
413 pbuf_free(buf);
414 return ERR_OK;
415 } else {
416 pbuf_free(buf);
417 return ERR_OK;
418 }
419 pbuf_free(buf);
420 altcp_abort(conn);
421 return ERR_ABRT;
422 } else {
423 err_t err;
424 if (ret) {
425 LWIP_ASSERT("bogus receive length", ret <= PBUF_POOL_BUFSIZE);
426 /* trim pool pbuf to actually decoded length */
427 pbuf_realloc(buf, (u16_t)ret);
428
429 state->bio_bytes_appl += ret;
430 if (mbedtls_ssl_get_bytes_avail(&state->ssl_context) == 0) {
431 /* Record is done, now we know the share between application and protocol bytes
432 and can adjust the RX window by the protocol bytes.
433 The rest is 'recved' by the application calling our 'recved' fn. */
434 int overhead_bytes;
435 LWIP_ASSERT("bogus byte counts", state->bio_bytes_read > state->bio_bytes_appl);
436 overhead_bytes = state->bio_bytes_read - state->bio_bytes_appl;
437 altcp_mbedtls_lower_recved(conn->inner_conn, overhead_bytes);
438 state->bio_bytes_read = 0;
439 state->bio_bytes_appl = 0;
440 }
441
442 if (state->rx_app == NULL) {
443 state->rx_app = buf;
444 } else {
445 pbuf_cat(state->rx_app, buf);
446 }
447 } else {
448 pbuf_free(buf);
449 buf = NULL;
450 }
451 err = altcp_mbedtls_pass_rx_data(conn, state);
452 if (err != ERR_OK) {
453 if (err == ERR_ABRT) {
454 /* recv callback needs to return this as the pcb is deallocated */
455 return ERR_ABRT;
456 }
457 /* we hide all other errors as we retry feeding the pbuf to the app later */
458 return ERR_OK;
459 }
460 }
461 } while (ret > 0);
462 return ERR_OK;
463 }
464
465 /** Receive callback function called from mbedtls (set via mbedtls_ssl_set_bio)
466 * This function mainly copies data from pbufs and frees the pbufs after copying.
467 */
468 static int
altcp_mbedtls_bio_recv(void * ctx,unsigned char * buf,size_t len)469 altcp_mbedtls_bio_recv(void *ctx, unsigned char *buf, size_t len)
470 {
471 struct altcp_pcb *conn = (struct altcp_pcb *)ctx;
472 altcp_mbedtls_state_t *state;
473 struct pbuf *p;
474 u16_t ret;
475 u16_t copy_len;
476 err_t err;
477
478 LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */
479 if ((conn == NULL) || (conn->state == NULL)) {
480 return MBEDTLS_ERR_NET_INVALID_CONTEXT;
481 }
482 state = (altcp_mbedtls_state_t *)conn->state;
483 LWIP_ASSERT("state != NULL", state != NULL);
484 p = state->rx;
485
486 /* @todo: return MBEDTLS_ERR_NET_CONN_RESET/MBEDTLS_ERR_NET_RECV_FAILED? */
487
488 if ((p == NULL) || ((p->len == 0) && (p->next == NULL))) {
489 if (p) {
490 pbuf_free(p);
491 }
492 state->rx = NULL;
493 if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) ==
494 ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) {
495 /* close queued but not passed up yet */
496 return 0;
497 }
498 return MBEDTLS_ERR_SSL_WANT_READ;
499 }
500 /* limit number of bytes again to copy from first pbuf in a chain only */
501 copy_len = (u16_t)LWIP_MIN(len, p->len);
502 /* copy the data */
503 ret = pbuf_copy_partial(p, buf, copy_len, 0);
504 LWIP_ASSERT("ret == copy_len", ret == copy_len);
505 /* hide the copied bytes from the pbuf */
506 err = pbuf_remove_header(p, ret);
507 LWIP_ASSERT("error", err == ERR_OK);
508 if (p->len == 0) {
509 /* the first pbuf has been fully read, free it */
510 state->rx = p->next;
511 p->next = NULL;
512 pbuf_free(p);
513 }
514
515 state->bio_bytes_read += (int)ret;
516 return ret;
517 }
518
519 /** Sent callback from lower connection (i.e. TCP)
520 * This only informs the upper layer the number of ACKed bytes.
521 * This now take care of TLS added bytes so application receive
522 * correct ACKed bytes.
523 */
524 static err_t
altcp_mbedtls_lower_sent(void * arg,struct altcp_pcb * inner_conn,u16_t len)525 altcp_mbedtls_lower_sent(void *arg, struct altcp_pcb *inner_conn, u16_t len)
526 {
527 struct altcp_pcb *conn = (struct altcp_pcb *)arg;
528 LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */
529 if (conn) {
530 int overhead;
531 u16_t app_len;
532 altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
533 LWIP_ASSERT("state", state != NULL);
534 LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
535 /* calculate TLS overhead part to not send it to application */
536 overhead = state->overhead_bytes_adjust + state->ssl_context.out_left;
537 if ((unsigned)overhead > len) {
538 overhead = len;
539 }
540 /* remove ACKed bytes from overhead adjust counter */
541 state->overhead_bytes_adjust -= len;
542 /* try to send more if we failed before (may increase overhead adjust counter) */
543 altcp_mbedtls_flush_output(state);
544 /* remove calculated overhead from ACKed bytes len */
545 app_len = len - (u16_t)overhead;
546 /* update application write counter and inform application */
547 if (app_len) {
548 state->overhead_bytes_adjust += app_len;
549 if (conn->sent)
550 return conn->sent(conn->arg, conn, app_len);
551 }
552 }
553 return ERR_OK;
554 }
555
556 /** Poll callback from lower connection (i.e. TCP)
557 * Just pass this on to the application.
558 * @todo: retry sending?
559 */
560 static err_t
altcp_mbedtls_lower_poll(void * arg,struct altcp_pcb * inner_conn)561 altcp_mbedtls_lower_poll(void *arg, struct altcp_pcb *inner_conn)
562 {
563 struct altcp_pcb *conn = (struct altcp_pcb *)arg;
564 LWIP_UNUSED_ARG(inner_conn); /* for LWIP_NOASSERT */
565 if (conn) {
566 LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
567 /* check if there's unreceived rx data */
568 if (conn->state) {
569 altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
570 /* try to send more if we failed before */
571 altcp_mbedtls_flush_output(state);
572 if (altcp_mbedtls_handle_rx_appldata(conn, state) == ERR_ABRT) {
573 return ERR_ABRT;
574 }
575 }
576 if (conn->poll) {
577 return conn->poll(conn->arg, conn);
578 }
579 }
580 return ERR_OK;
581 }
582
583 static void
altcp_mbedtls_lower_err(void * arg,err_t err)584 altcp_mbedtls_lower_err(void *arg, err_t err)
585 {
586 struct altcp_pcb *conn = (struct altcp_pcb *)arg;
587 if (conn) {
588 conn->inner_conn = NULL; /* already freed */
589 if (conn->err) {
590 conn->err(conn->arg, err);
591 }
592 altcp_free(conn);
593 }
594 }
595
596 /* setup functions */
597
598 static void
altcp_mbedtls_remove_callbacks(struct altcp_pcb * inner_conn)599 altcp_mbedtls_remove_callbacks(struct altcp_pcb *inner_conn)
600 {
601 altcp_arg(inner_conn, NULL);
602 altcp_recv(inner_conn, NULL);
603 altcp_sent(inner_conn, NULL);
604 altcp_err(inner_conn, NULL);
605 altcp_poll(inner_conn, NULL, inner_conn->pollinterval);
606 }
607
608 static void
altcp_mbedtls_setup_callbacks(struct altcp_pcb * conn,struct altcp_pcb * inner_conn)609 altcp_mbedtls_setup_callbacks(struct altcp_pcb *conn, struct altcp_pcb *inner_conn)
610 {
611 altcp_arg(inner_conn, conn);
612 altcp_recv(inner_conn, altcp_mbedtls_lower_recv);
613 altcp_sent(inner_conn, altcp_mbedtls_lower_sent);
614 altcp_err(inner_conn, altcp_mbedtls_lower_err);
615 /* tcp_poll is set when interval is set by application */
616 /* listen is set totally different :-) */
617 }
618
619 static err_t
altcp_mbedtls_setup(void * conf,struct altcp_pcb * conn,struct altcp_pcb * inner_conn)620 altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn)
621 {
622 int ret;
623 struct altcp_tls_config *config = (struct altcp_tls_config *)conf;
624 altcp_mbedtls_state_t *state;
625 if (!conf) {
626 return ERR_ARG;
627 }
628 LWIP_ASSERT("invalid inner_conn", conn != inner_conn);
629
630 /* allocate mbedtls context */
631 state = altcp_mbedtls_alloc(conf);
632 if (state == NULL) {
633 return ERR_MEM;
634 }
635 /* initialize mbedtls context: */
636 mbedtls_ssl_init(&state->ssl_context);
637 ret = mbedtls_ssl_setup(&state->ssl_context, &config->conf);
638 if (ret != 0) {
639 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_setup failed\n"));
640 /* @todo: convert 'ret' to err_t */
641 altcp_mbedtls_free(conf, state);
642 return ERR_MEM;
643 }
644 /* tell mbedtls about our I/O functions */
645 mbedtls_ssl_set_bio(&state->ssl_context, conn, altcp_mbedtls_bio_send, altcp_mbedtls_bio_recv, NULL);
646
647 altcp_mbedtls_setup_callbacks(conn, inner_conn);
648 conn->inner_conn = inner_conn;
649 conn->fns = &altcp_mbedtls_functions;
650 conn->state = state;
651 return ERR_OK;
652 }
653
654 struct altcp_pcb *
altcp_tls_wrap(struct altcp_tls_config * config,struct altcp_pcb * inner_pcb)655 altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb)
656 {
657 struct altcp_pcb *ret;
658 if (inner_pcb == NULL) {
659 return NULL;
660 }
661 ret = altcp_alloc();
662 if (ret != NULL) {
663 if (altcp_mbedtls_setup(config, ret, inner_pcb) != ERR_OK) {
664 altcp_free(ret);
665 return NULL;
666 }
667 }
668 return ret;
669 }
670
671 void
altcp_tls_init_session(struct altcp_tls_session * session)672 altcp_tls_init_session(struct altcp_tls_session *session)
673 {
674 if (session)
675 mbedtls_ssl_session_init(&session->data);
676 }
677
678 err_t
altcp_tls_get_session(struct altcp_pcb * conn,struct altcp_tls_session * session)679 altcp_tls_get_session(struct altcp_pcb *conn, struct altcp_tls_session *session)
680 {
681 if (session && conn && conn->state) {
682 altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
683 int ret = mbedtls_ssl_get_session(&state->ssl_context, &session->data);
684 return ret < 0 ? ERR_VAL : ERR_OK;
685 }
686 return ERR_ARG;
687 }
688
689 err_t
altcp_tls_set_session(struct altcp_pcb * conn,struct altcp_tls_session * session)690 altcp_tls_set_session(struct altcp_pcb *conn, struct altcp_tls_session *session)
691 {
692 if (session && conn && conn->state) {
693 altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
694 int ret = -1;
695 if (session->data.start)
696 ret = mbedtls_ssl_set_session(&state->ssl_context, &session->data);
697 return ret < 0 ? ERR_VAL : ERR_OK;
698 }
699 return ERR_ARG;
700 }
701
702 void
altcp_tls_free_session(struct altcp_tls_session * session)703 altcp_tls_free_session(struct altcp_tls_session *session)
704 {
705 if (session)
706 mbedtls_ssl_session_free(&session->data);
707 }
708
709 void *
altcp_tls_context(struct altcp_pcb * conn)710 altcp_tls_context(struct altcp_pcb *conn)
711 {
712 if (conn && conn->state) {
713 altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
714 return &state->ssl_context;
715 }
716 return NULL;
717 }
718
719 #if ALTCP_MBEDTLS_LIB_DEBUG != LWIP_DBG_OFF
720 static void
altcp_mbedtls_debug(void * ctx,int level,const char * file,int line,const char * str)721 altcp_mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str)
722 {
723 LWIP_UNUSED_ARG(ctx);
724 LWIP_UNUSED_ARG(file);
725 LWIP_UNUSED_ARG(line);
726 LWIP_UNUSED_ARG(str);
727
728 if (level >= ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN) {
729 LWIP_DEBUGF(ALTCP_MBEDTLS_LIB_DEBUG, ("%s:%04d: %s\n", file, line, str));
730 }
731 }
732 #endif
733
734 static err_t
altcp_mbedtls_ref_entropy(void)735 altcp_mbedtls_ref_entropy(void)
736 {
737 LWIP_ASSERT_CORE_LOCKED();
738
739 if (!altcp_tls_entropy_rng) {
740 altcp_tls_entropy_rng = (struct altcp_tls_entropy_rng *)altcp_mbedtls_alloc_config(sizeof(struct altcp_tls_entropy_rng));
741 if (altcp_tls_entropy_rng) {
742 int ret;
743 altcp_tls_entropy_rng->ref = 1;
744 mbedtls_entropy_init(&altcp_tls_entropy_rng->entropy);
745 mbedtls_ctr_drbg_init(&altcp_tls_entropy_rng->ctr_drbg);
746 /* Seed the RNG, only once */
747 ret = mbedtls_ctr_drbg_seed(&altcp_tls_entropy_rng->ctr_drbg,
748 ALTCP_MBEDTLS_RNG_FN, &altcp_tls_entropy_rng->entropy,
749 ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN);
750 if (ret != 0) {
751 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret));
752 mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
753 mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
754 altcp_mbedtls_free_config(altcp_tls_entropy_rng);
755 altcp_tls_entropy_rng = NULL;
756 return ERR_ARG;
757 }
758 } else {
759 return ERR_MEM;
760 }
761 } else {
762 altcp_tls_entropy_rng->ref++;
763 }
764 return ERR_OK;
765 }
766
767 static void
altcp_mbedtls_unref_entropy(void)768 altcp_mbedtls_unref_entropy(void)
769 {
770 LWIP_ASSERT_CORE_LOCKED();
771
772 if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref) {
773 altcp_tls_entropy_rng->ref--;
774 }
775 }
776
777 /** Create new TLS configuration
778 * ATTENTION: Server certificate and private key have to be added outside this function!
779 */
780 static struct altcp_tls_config *
altcp_tls_create_config(int is_server,u8_t cert_count,u8_t pkey_count,int have_ca)781 altcp_tls_create_config(int is_server, u8_t cert_count, u8_t pkey_count, int have_ca)
782 {
783 size_t sz;
784 int ret;
785 struct altcp_tls_config *conf;
786 mbedtls_x509_crt *mem;
787
788 if (TCP_WND < MBEDTLS_SSL_MAX_CONTENT_LEN) {
789 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG|LWIP_DBG_LEVEL_SERIOUS,
790 ("altcp_tls: TCP_WND is smaller than the RX decrypion buffer, connection RX might stall!\n"));
791 }
792
793 altcp_mbedtls_mem_init();
794
795 sz = sizeof(struct altcp_tls_config);
796 if (cert_count > 0) {
797 sz += (cert_count * sizeof(mbedtls_x509_crt));
798 }
799 if (have_ca) {
800 sz += sizeof(mbedtls_x509_crt);
801 }
802 if (pkey_count > 0) {
803 sz += (pkey_count * sizeof(mbedtls_pk_context));
804 }
805
806 conf = (struct altcp_tls_config *)altcp_mbedtls_alloc_config(sz);
807 if (conf == NULL) {
808 return NULL;
809 }
810 conf->cert_max = cert_count;
811 mem = (mbedtls_x509_crt *)(conf + 1);
812 if (cert_count > 0) {
813 conf->cert = mem;
814 mem += cert_count;
815 }
816 if (have_ca) {
817 conf->ca = mem;
818 mem++;
819 }
820 conf->pkey_max = pkey_count;
821 if (pkey_count > 0) {
822 conf->pkey = (mbedtls_pk_context *)mem;
823 }
824
825 mbedtls_ssl_config_init(&conf->conf);
826
827 if (altcp_mbedtls_ref_entropy() != ERR_OK) {
828 altcp_mbedtls_free_config(conf);
829 return NULL;
830 }
831
832 /* Setup ssl context (@todo: what's different for a client here? -> might better be done on listen/connect) */
833 ret = mbedtls_ssl_config_defaults(&conf->conf, is_server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
834 MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
835 if (ret != 0) {
836 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_config_defaults failed: %d\n", ret));
837 altcp_mbedtls_unref_entropy();
838 altcp_mbedtls_free_config(conf);
839 return NULL;
840 }
841 mbedtls_ssl_conf_authmode(&conf->conf, ALTCP_MBEDTLS_AUTHMODE);
842
843 mbedtls_ssl_conf_rng(&conf->conf, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg);
844 #if ALTCP_MBEDTLS_LIB_DEBUG != LWIP_DBG_OFF
845 mbedtls_ssl_conf_dbg(&conf->conf, altcp_mbedtls_debug, stdout);
846 #endif
847 #if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
848 mbedtls_ssl_conf_session_cache(&conf->conf, &conf->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set);
849 mbedtls_ssl_cache_set_timeout(&conf->cache, ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS);
850 mbedtls_ssl_cache_set_max_entries(&conf->cache, ALTCP_MBEDTLS_SESSION_CACHE_SIZE);
851 #endif
852
853 #if defined(MBEDTLS_SSL_SESSION_TICKETS) && ALTCP_MBEDTLS_USE_SESSION_TICKETS
854 mbedtls_ssl_ticket_init(&conf->ticket_ctx);
855
856 ret = mbedtls_ssl_ticket_setup(&conf->ticket_ctx, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg,
857 ALTCP_MBEDTLS_SESSION_TICKET_CIPHER, ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS);
858 if (ret) {
859 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_ticket_setup failed: %d\n", ret));
860 altcp_mbedtls_unref_entropy();
861 altcp_mbedtls_free_config(conf);
862 return NULL;
863 }
864
865 mbedtls_ssl_conf_session_tickets_cb(&conf->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse,
866 &conf->ticket_ctx);
867 #endif
868
869 return conf;
870 }
871
altcp_tls_create_config_server(u8_t cert_count)872 struct altcp_tls_config *altcp_tls_create_config_server(u8_t cert_count)
873 {
874 struct altcp_tls_config *conf = altcp_tls_create_config(1, cert_count, cert_count, 0);
875 if (conf == NULL) {
876 return NULL;
877 }
878
879 mbedtls_ssl_conf_ca_chain(&conf->conf, NULL, NULL);
880 return conf;
881 }
882
altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config * config,const u8_t * privkey,size_t privkey_len,const u8_t * privkey_pass,size_t privkey_pass_len,const u8_t * cert,size_t cert_len)883 err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config,
884 const u8_t *privkey, size_t privkey_len,
885 const u8_t *privkey_pass, size_t privkey_pass_len,
886 const u8_t *cert, size_t cert_len)
887 {
888 int ret;
889 mbedtls_x509_crt *srvcert;
890 mbedtls_pk_context *pkey;
891
892 if (config->cert_count >= config->cert_max) {
893 return ERR_MEM;
894 }
895 if (config->pkey_count >= config->pkey_max) {
896 return ERR_MEM;
897 }
898
899 srvcert = config->cert + config->cert_count;
900 mbedtls_x509_crt_init(srvcert);
901
902 pkey = config->pkey + config->pkey_count;
903 mbedtls_pk_init(pkey);
904
905 /* Load the certificates and private key */
906 ret = mbedtls_x509_crt_parse(srvcert, cert, cert_len);
907 if (ret != 0) {
908 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d\n", ret));
909 return ERR_VAL;
910 }
911
912 ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len);
913 if (ret != 0) {
914 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
915 mbedtls_x509_crt_free(srvcert);
916 return ERR_VAL;
917 }
918
919 ret = mbedtls_ssl_conf_own_cert(&config->conf, srvcert, pkey);
920 if (ret != 0) {
921 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d\n", ret));
922 mbedtls_x509_crt_free(srvcert);
923 mbedtls_pk_free(pkey);
924 return ERR_VAL;
925 }
926
927 config->cert_count++;
928 config->pkey_count++;
929 return ERR_OK;
930 }
931
932 /** Create new TLS configuration
933 * This is a suboptimal version that gets the encrypted private key and its password,
934 * as well as the server certificate.
935 */
936 struct altcp_tls_config *
altcp_tls_create_config_server_privkey_cert(const u8_t * privkey,size_t privkey_len,const u8_t * privkey_pass,size_t privkey_pass_len,const u8_t * cert,size_t cert_len)937 altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len,
938 const u8_t *privkey_pass, size_t privkey_pass_len,
939 const u8_t *cert, size_t cert_len)
940 {
941 struct altcp_tls_config *conf = altcp_tls_create_config_server(1);
942 if (conf == NULL) {
943 return NULL;
944 }
945
946 if (altcp_tls_config_server_add_privkey_cert(conf, privkey, privkey_len,
947 privkey_pass, privkey_pass_len, cert, cert_len) != ERR_OK) {
948 altcp_tls_free_config(conf);
949 return NULL;
950 }
951
952 return conf;
953 }
954
955 static struct altcp_tls_config *
altcp_tls_create_config_client_common(const u8_t * ca,size_t ca_len,int is_2wayauth)956 altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth)
957 {
958 int ret;
959 struct altcp_tls_config *conf = altcp_tls_create_config(0, (is_2wayauth) ? 1 : 0, (is_2wayauth) ? 1 : 0, ca != NULL);
960 if (conf == NULL) {
961 return NULL;
962 }
963
964 /* Initialize the CA certificate if provided
965 * CA certificate is optional (to save memory) but recommended for production environment
966 * Without CA certificate, connection will be prone to man-in-the-middle attacks */
967 if (ca) {
968 mbedtls_x509_crt_init(conf->ca);
969 ret = mbedtls_x509_crt_parse(conf->ca, ca, ca_len);
970 if (ret != 0) {
971 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse ca failed: %d 0x%x\n", ret, -1*ret));
972 altcp_tls_free_config(conf);
973 return NULL;
974 }
975
976 mbedtls_ssl_conf_ca_chain(&conf->conf, conf->ca, NULL);
977 }
978 return conf;
979 }
980
981 struct altcp_tls_config *
altcp_tls_create_config_client(const u8_t * ca,size_t ca_len)982 altcp_tls_create_config_client(const u8_t *ca, size_t ca_len)
983 {
984 return altcp_tls_create_config_client_common(ca, ca_len, 0);
985 }
986
987 struct altcp_tls_config *
altcp_tls_create_config_client_2wayauth(const u8_t * ca,size_t ca_len,const u8_t * privkey,size_t privkey_len,const u8_t * privkey_pass,size_t privkey_pass_len,const u8_t * cert,size_t cert_len)988 altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_t *privkey, size_t privkey_len,
989 const u8_t *privkey_pass, size_t privkey_pass_len,
990 const u8_t *cert, size_t cert_len)
991 {
992 int ret;
993 struct altcp_tls_config *conf;
994
995 if (!cert || !privkey) {
996 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("altcp_tls_create_config_client_2wayauth: certificate and priv key required\n"));
997 return NULL;
998 }
999
1000 conf = altcp_tls_create_config_client_common(ca, ca_len, 1);
1001 if (conf == NULL) {
1002 return NULL;
1003 }
1004
1005 /* Initialize the client certificate and corresponding private key */
1006 mbedtls_x509_crt_init(conf->cert);
1007 ret = mbedtls_x509_crt_parse(conf->cert, cert, cert_len);
1008 if (ret != 0) {
1009 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse cert failed: %d 0x%x\n", ret, -1*ret));
1010 altcp_tls_free_config(conf);
1011 return NULL;
1012 }
1013
1014 mbedtls_pk_init(conf->pkey);
1015 ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len);
1016 if (ret != 0) {
1017 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x\n", ret, -1*ret));
1018 altcp_tls_free_config(conf);
1019 return NULL;
1020 }
1021
1022 ret = mbedtls_ssl_conf_own_cert(&conf->conf, conf->cert, conf->pkey);
1023 if (ret != 0) {
1024 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d 0x%x\n", ret, -1*ret));
1025 altcp_tls_free_config(conf);
1026 return NULL;
1027 }
1028
1029 return conf;
1030 }
1031
1032 int
altcp_tls_configure_alpn_protocols(struct altcp_tls_config * conf,const char ** protos)1033 altcp_tls_configure_alpn_protocols(struct altcp_tls_config *conf, const char **protos)
1034 {
1035 #if defined(MBEDTLS_SSL_ALPN)
1036 int ret = mbedtls_ssl_conf_alpn_protocols(&conf->conf, protos);
1037 if (ret != 0) {
1038 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_alpn_protocols failed: %d\n", ret));
1039 }
1040
1041 return ret;
1042 #else
1043 return -1;
1044 #endif
1045 }
1046
1047 void
altcp_tls_free_config(struct altcp_tls_config * conf)1048 altcp_tls_free_config(struct altcp_tls_config *conf)
1049 {
1050 if (conf->pkey) {
1051 mbedtls_pk_free(conf->pkey);
1052 }
1053 if (conf->cert) {
1054 mbedtls_x509_crt_free(conf->cert);
1055 }
1056 if (conf->ca) {
1057 mbedtls_x509_crt_free(conf->ca);
1058 }
1059 mbedtls_ssl_config_free(&conf->conf);
1060 altcp_mbedtls_free_config(conf);
1061 altcp_mbedtls_unref_entropy();
1062 }
1063
1064 void
altcp_tls_free_entropy(void)1065 altcp_tls_free_entropy(void)
1066 {
1067 LWIP_ASSERT_CORE_LOCKED();
1068
1069 if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref == 0) {
1070 mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
1071 mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
1072 altcp_mbedtls_free_config(altcp_tls_entropy_rng);
1073 altcp_tls_entropy_rng = NULL;
1074 }
1075 }
1076
1077 /* "virtual" functions */
1078 static void
altcp_mbedtls_set_poll(struct altcp_pcb * conn,u8_t interval)1079 altcp_mbedtls_set_poll(struct altcp_pcb *conn, u8_t interval)
1080 {
1081 if (conn != NULL) {
1082 altcp_poll(conn->inner_conn, altcp_mbedtls_lower_poll, interval);
1083 }
1084 }
1085
1086 static void
altcp_mbedtls_recved(struct altcp_pcb * conn,u16_t len)1087 altcp_mbedtls_recved(struct altcp_pcb *conn, u16_t len)
1088 {
1089 u16_t lower_recved;
1090 altcp_mbedtls_state_t *state;
1091 if (conn == NULL) {
1092 return;
1093 }
1094 state = (altcp_mbedtls_state_t *)conn->state;
1095 if (state == NULL) {
1096 return;
1097 }
1098 if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
1099 return;
1100 }
1101 lower_recved = len;
1102 if (lower_recved > state->rx_passed_unrecved) {
1103 LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("bogus recved count (len > state->rx_passed_unrecved / %d / %d)\n",
1104 len, state->rx_passed_unrecved));
1105 lower_recved = (u16_t)state->rx_passed_unrecved;
1106 }
1107 state->rx_passed_unrecved -= lower_recved;
1108
1109 altcp_recved(conn->inner_conn, lower_recved);
1110 }
1111
1112 static err_t
altcp_mbedtls_connect(struct altcp_pcb * conn,const ip_addr_t * ipaddr,u16_t port,altcp_connected_fn connected)1113 altcp_mbedtls_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected)
1114 {
1115 if (conn == NULL) {
1116 return ERR_VAL;
1117 }
1118 conn->connected = connected;
1119 return altcp_connect(conn->inner_conn, ipaddr, port, altcp_mbedtls_lower_connected);
1120 }
1121
1122 static struct altcp_pcb *
altcp_mbedtls_listen(struct altcp_pcb * conn,u8_t backlog,err_t * err)1123 altcp_mbedtls_listen(struct altcp_pcb *conn, u8_t backlog, err_t *err)
1124 {
1125 struct altcp_pcb *lpcb;
1126 if (conn == NULL) {
1127 return NULL;
1128 }
1129 lpcb = altcp_listen_with_backlog_and_err(conn->inner_conn, backlog, err);
1130 if (lpcb != NULL) {
1131 altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
1132 /* Free members of the ssl context (not used on listening pcb). This
1133 includes freeing input/output buffers, so saves ~32KByte by default */
1134 mbedtls_ssl_free(&state->ssl_context);
1135
1136 conn->inner_conn = lpcb;
1137 altcp_accept(lpcb, altcp_mbedtls_lower_accept);
1138 return conn;
1139 }
1140 return NULL;
1141 }
1142
1143 static void
altcp_mbedtls_abort(struct altcp_pcb * conn)1144 altcp_mbedtls_abort(struct altcp_pcb *conn)
1145 {
1146 if (conn != NULL) {
1147 altcp_abort(conn->inner_conn);
1148 }
1149 }
1150
1151 static err_t
altcp_mbedtls_close(struct altcp_pcb * conn)1152 altcp_mbedtls_close(struct altcp_pcb *conn)
1153 {
1154 struct altcp_pcb *inner_conn;
1155 if (conn == NULL) {
1156 return ERR_VAL;
1157 }
1158 inner_conn = conn->inner_conn;
1159 if (inner_conn) {
1160 err_t err;
1161 altcp_poll_fn oldpoll = inner_conn->poll;
1162 altcp_mbedtls_remove_callbacks(conn->inner_conn);
1163 err = altcp_close(conn->inner_conn);
1164 if (err != ERR_OK) {
1165 /* not closed, set up all callbacks again */
1166 altcp_mbedtls_setup_callbacks(conn, inner_conn);
1167 /* poll callback is not included in the above */
1168 altcp_poll(inner_conn, oldpoll, inner_conn->pollinterval);
1169 return err;
1170 }
1171 conn->inner_conn = NULL;
1172 }
1173 altcp_free(conn);
1174 return ERR_OK;
1175 }
1176
1177 /** Allow caller of altcp_write() to limit to negotiated chunk size
1178 * or remaining sndbuf space of inner_conn.
1179 */
1180 static u16_t
altcp_mbedtls_sndbuf(struct altcp_pcb * conn)1181 altcp_mbedtls_sndbuf(struct altcp_pcb *conn)
1182 {
1183 if (conn) {
1184 altcp_mbedtls_state_t *state;
1185 state = (altcp_mbedtls_state_t*)conn->state;
1186 if (!state || !(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
1187 return 0;
1188 }
1189 if (conn->inner_conn) {
1190 u16_t sndbuf = altcp_sndbuf(conn->inner_conn);
1191 /* Take care of record header, IV, AuthTag */
1192 int ssl_expan = mbedtls_ssl_get_record_expansion(&state->ssl_context);
1193 if (ssl_expan > 0) {
1194 size_t ssl_added = (u16_t)LWIP_MIN(ssl_expan, 0xFFFF);
1195 /* internal sndbuf smaller than our offset */
1196 if (ssl_added < sndbuf) {
1197 size_t max_len = 0xFFFF;
1198 size_t ret;
1199 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1200 /* @todo: adjust ssl_added to real value related to negotiated cipher */
1201 size_t max_frag_len = mbedtls_ssl_get_max_frag_len(&state->ssl_context);
1202 max_len = LWIP_MIN(max_frag_len, max_len);
1203 #endif
1204 /* Adjust sndbuf of inner_conn with what added by SSL */
1205 ret = LWIP_MIN(sndbuf - ssl_added, max_len);
1206 LWIP_ASSERT("sndbuf overflow", ret <= 0xFFFF);
1207 return (u16_t)ret;
1208 }
1209 }
1210 }
1211 }
1212 /* fallback: use sendbuf of the inner connection */
1213 return altcp_default_sndbuf(conn);
1214 }
1215
1216 /** Write data to a TLS connection. Calls into mbedTLS, which in turn calls into
1217 * @ref altcp_mbedtls_bio_send() to send the encrypted data
1218 */
1219 static err_t
altcp_mbedtls_write(struct altcp_pcb * conn,const void * dataptr,u16_t len,u8_t apiflags)1220 altcp_mbedtls_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags)
1221 {
1222 int ret;
1223 altcp_mbedtls_state_t *state;
1224
1225 LWIP_UNUSED_ARG(apiflags);
1226
1227 if (conn == NULL) {
1228 return ERR_VAL;
1229 }
1230
1231 state = (altcp_mbedtls_state_t *)conn->state;
1232 if (state == NULL) {
1233 /* @todo: which error? */
1234 return ERR_ARG;
1235 }
1236 if (!(state->flags & ALTCP_MBEDTLS_FLAGS_HANDSHAKE_DONE)) {
1237 /* @todo: which error? */
1238 return ERR_VAL;
1239 }
1240
1241 /* HACK: if there is something left to send, try to flush it and only
1242 allow sending more if this succeeded (this is a hack because neither
1243 returning 0 nor MBEDTLS_ERR_SSL_WANT_WRITE worked for me) */
1244 if (state->ssl_context.out_left) {
1245 altcp_mbedtls_flush_output(state);
1246 if (state->ssl_context.out_left) {
1247 return ERR_MEM;
1248 }
1249 }
1250 ret = mbedtls_ssl_write(&state->ssl_context, (const unsigned char *)dataptr, len);
1251 /* try to send data... */
1252 altcp_output(conn->inner_conn);
1253 if (ret >= 0) {
1254 if (ret == len) {
1255 /* update application sent counter */
1256 state->overhead_bytes_adjust -= ret;
1257 return ERR_OK;
1258 } else {
1259 /* @todo/@fixme: assumption: either everything sent or error */
1260 LWIP_ASSERT("ret <= 0", 0);
1261 return ERR_MEM;
1262 }
1263 } else {
1264 if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
1265 /* @todo: convert error to err_t */
1266 return ERR_MEM;
1267 }
1268 LWIP_ASSERT("unhandled error", 0);
1269 return ERR_VAL;
1270 }
1271 }
1272
1273 /** Send callback function called from mbedtls (set via mbedtls_ssl_set_bio)
1274 * This function is either called during handshake or when sending application
1275 * data via @ref altcp_mbedtls_write (or altcp_write)
1276 */
1277 static int
altcp_mbedtls_bio_send(void * ctx,const unsigned char * dataptr,size_t size)1278 altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size)
1279 {
1280 struct altcp_pcb *conn = (struct altcp_pcb *) ctx;
1281 altcp_mbedtls_state_t *state;
1282 int written = 0;
1283 size_t size_left = size;
1284 u8_t apiflags = TCP_WRITE_FLAG_COPY;
1285
1286 LWIP_ASSERT("conn != NULL", conn != NULL);
1287 if ((conn == NULL) || (conn->inner_conn == NULL)) {
1288 return MBEDTLS_ERR_NET_INVALID_CONTEXT;
1289 }
1290 state = (altcp_mbedtls_state_t *)conn->state;
1291 LWIP_ASSERT("state != NULL", state != NULL);
1292
1293 while (size_left) {
1294 u16_t write_len = (u16_t)LWIP_MIN(size_left, 0xFFFF);
1295 err_t err = altcp_write(conn->inner_conn, (const void *)dataptr, write_len, apiflags);
1296 if (err == ERR_OK) {
1297 written += write_len;
1298 size_left -= write_len;
1299 state->overhead_bytes_adjust += write_len;
1300 } else if (err == ERR_MEM) {
1301 if (written) {
1302 return written;
1303 }
1304 return 0; /* MBEDTLS_ERR_SSL_WANT_WRITE; */
1305 } else {
1306 LWIP_ASSERT("tls_write, tcp_write: err != ERR MEM", 0);
1307 /* @todo: return MBEDTLS_ERR_NET_CONN_RESET or MBEDTLS_ERR_NET_SEND_FAILED */
1308 return MBEDTLS_ERR_NET_SEND_FAILED;
1309 }
1310 }
1311 return written;
1312 }
1313
1314 static u16_t
altcp_mbedtls_mss(struct altcp_pcb * conn)1315 altcp_mbedtls_mss(struct altcp_pcb *conn)
1316 {
1317 if (conn == NULL) {
1318 return 0;
1319 }
1320 /* @todo: LWIP_MIN(mss, mbedtls_ssl_get_max_frag_len()) ? */
1321 return altcp_mss(conn->inner_conn);
1322 }
1323
1324 static void
altcp_mbedtls_dealloc(struct altcp_pcb * conn)1325 altcp_mbedtls_dealloc(struct altcp_pcb *conn)
1326 {
1327 /* clean up and free tls state */
1328 if (conn) {
1329 altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
1330 if (state) {
1331 mbedtls_ssl_free(&state->ssl_context);
1332 state->flags = 0;
1333 if (state->rx) {
1334 /* free leftover (unhandled) rx pbufs */
1335 pbuf_free(state->rx);
1336 state->rx = NULL;
1337 }
1338 altcp_mbedtls_free(state->conf, state);
1339 conn->state = NULL;
1340 }
1341 }
1342 }
1343
1344 const struct altcp_functions altcp_mbedtls_functions = {
1345 altcp_mbedtls_set_poll,
1346 altcp_mbedtls_recved,
1347 altcp_default_bind,
1348 altcp_mbedtls_connect,
1349 altcp_mbedtls_listen,
1350 altcp_mbedtls_abort,
1351 altcp_mbedtls_close,
1352 altcp_default_shutdown,
1353 altcp_mbedtls_write,
1354 altcp_default_output,
1355 altcp_mbedtls_mss,
1356 altcp_mbedtls_sndbuf,
1357 altcp_default_sndqueuelen,
1358 altcp_default_nagle_disable,
1359 altcp_default_nagle_enable,
1360 altcp_default_nagle_disabled,
1361 altcp_default_setprio,
1362 altcp_mbedtls_dealloc,
1363 altcp_default_get_tcp_addrinfo,
1364 altcp_default_get_ip,
1365 altcp_default_get_port
1366 #if LWIP_TCP_KEEPALIVE
1367 , altcp_default_keepalive_disable
1368 , altcp_default_keepalive_enable
1369 #endif
1370 #ifdef LWIP_DEBUG
1371 , altcp_default_dbg_get_tcp_state
1372 #endif
1373 };
1374
1375 #endif /* LWIP_ALTCP_TLS && LWIP_ALTCP_TLS_MBEDTLS */
1376 #endif /* LWIP_ALTCP */
1377