Skip to content

Commit 5d578fc

Browse files
committed
avs_commons 5.4.0
BREAKING CHANGES - Default POSIX socket implementation now doesn't include ``errno.h`` if definition of ``EDOM`` (available by e.g. including lwIP's ``lwip/errno.h``) is included in ``AVS_COMMONS_POSIX_COMPAT_HEADER``. Improvements - Made MD5 length define publicly visible (for easier avs_stream_md5 usage) - Made (D)TLS session resumption and persistence possible on Mbed TLS 3.0+ even when MBEDTLS_SSL_SRV_C is disabled Bugfixes - Added missing null guards in (D)TLS socket implementations so that all methods are now safe to call in any state - When using lwIP, default POSIX socket implementation and appropriate compat header now include lwIP's ``lwip/errno.h`` instead of system ``errno.h``
1 parent a227958 commit 5d578fc

13 files changed

Lines changed: 152 additions & 102 deletions

File tree

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Changelog
22

3+
## avs_commons 5.4.0 (September 7th, 2023)
4+
5+
### BREAKING CHANGES
6+
7+
* Default POSIX socket implementation now doesn't include ``errno.h`` if
8+
definition of ``EDOM`` (available by e.g. including lwIP's ``lwip/errno.h``)
9+
is included in ``AVS_COMMONS_POSIX_COMPAT_HEADER``.
10+
11+
### Improvements
12+
13+
* Made MD5 length define publicly visible (for easier avs_stream_md5 usage)
14+
* Made (D)TLS session resumption and persistence possible on Mbed TLS 3.0+ even
15+
when MBEDTLS_SSL_SRV_C is disabled
16+
17+
### Bugfixes
18+
19+
* Added missing null guards in (D)TLS socket implementations so that all methods
20+
are now safe to call in any state
21+
* When using lwIP, default POSIX socket implementation and appropriate compat
22+
header now include lwIP's ``lwip/errno.h`` instead of system ``errno.h``
23+
324
## avs_commons 5.3.1 (June 12th, 2023)
425

526
### Features

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
cmake_minimum_required(VERSION 3.6.0)
1818
project(avs_commons C)
1919

20-
set(AVS_COMMONS_VERSION "5.3.1")
20+
set(AVS_COMMONS_VERSION "5.4.0")
2121

2222
################# DISTRIBUTION #################################################
2323

compat/lwip-posix-compat.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727

2828
#include "lwipopts.h"
2929

30+
/* Provides lwIP's alternative errno header, used in avs_net_impl.c */
31+
#include "lwip/errno.h"
32+
3033
/* Provides htons/ntohs/htonl/ntohl */
3134
#include "lwip/inet.h"
3235

include_public/avsystem/commons/avs_errno_map.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
extern "C" {
2424
#endif
2525

26-
// Note: It might seem more appropriate to write #ifndef errno, but even though
27-
// ISO C defines errno as being a macro, on some platforms (e.g. lwIP) it isn't
28-
// a macro, but rather just an external linkage symbol.
26+
// Note: It might seem more appropriate to write #ifndef errno, but wording
27+
// seems to allow to errno to be not a macro, but an external linkage symbol and
28+
// lwIP does just that.
2929
#ifndef EDOM
3030
# error "For this header to be useful, you have to include your system / library / whatever errno.h first."
3131
#endif // EDOM

include_public/avsystem/commons/avs_stream_md5.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
extern "C" {
2424
#endif
2525

26+
#define AVS_COMMONS_MD5_LENGTH 16
27+
2628
avs_stream_t *avs_stream_md5_create(void);
2729

2830
#ifdef __cplusplus

src/crypto/mbedtls/avs_mbedtls_private.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,39 @@ static inline int mbedtls_ssl_is_handshake_over(mbedtls_ssl_context *ssl) {
165165
return ssl->MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_HANDSHAKE_OVER;
166166
}
167167
# endif // MBEDTLS_VERSION_NUMBER < 0x03020000
168+
169+
# ifndef MBEDTLS_SSL_SRV_C
170+
// HACK: We (ab)use mbedtls_ssl_conf_session_cache() in avs_net to detect
171+
// whether a (D)TLS session has been resumed or a new one has been created.
172+
// However, this API is normally used for handling session cache, which only
173+
// makes sense on the server side - hence, this function is only defined by
174+
// Mbed TLS if MBEDTLS_SSL_SRV_C is enabled. However, the fields in
175+
// mbedtls_ssl_config and the code that actually calls f_set_cache is compiled
176+
// unconditionally. So we define our own clone of
177+
// mbedtls_ssl_conf_session_cache() if MBEDTLS_SSL_SRV_C is disabled.
178+
//
179+
// Additionally, in Mbed TLS 2.x, there were no typedefs for the f_get_cache
180+
// and f_set_cache function pointers. We define those here to make the setter
181+
// below compatible with both 2.x and 3.x lines. Note that the f_get_cache and
182+
// f_set_cache function signatures are different between Mbed TLS 2.x and 3.x -
183+
// we define the 2.x variants here, because the typedefs are already there in
184+
// 3.x. The difference in actual signatures is handled in avs_mbedtls_socket.c.
185+
# if MBEDTLS_VERSION_NUMBER < 0x03000000
186+
typedef int mbedtls_ssl_cache_get_t(void *data, mbedtls_ssl_session *session);
187+
typedef int mbedtls_ssl_cache_set_t(void *data,
188+
const mbedtls_ssl_session *session);
189+
# endif // MBEDTLS_VERSION_NUMBER < 0x03000000
190+
191+
static inline void
192+
mbedtls_ssl_conf_session_cache(mbedtls_ssl_config *conf,
193+
void *p_cache,
194+
mbedtls_ssl_cache_get_t *f_get_cache,
195+
mbedtls_ssl_cache_set_t *f_set_cache) {
196+
conf->MBEDTLS_PRIVATE(p_cache) = p_cache;
197+
conf->MBEDTLS_PRIVATE(f_get_cache) = f_get_cache;
198+
conf->MBEDTLS_PRIVATE(f_set_cache) = f_set_cache;
199+
}
200+
# endif // MBEDTLS_SSL_SRV_C
168201
#endif // AVS_COMMONS_WITH_AVS_NET
169202

170203
#if defined(AVS_COMMONS_WITH_AVS_NET) \

src/net/avs_ssl_common.h

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,11 @@ static const void *system_socket_ssl(avs_net_socket_t *socket_) {
218218
static avs_error_t shutdown_ssl(avs_net_socket_t *socket_) {
219219
LOG(TRACE, _("shutdown_ssl(socket=") "%p" _(")"), (void *) socket_);
220220
ssl_socket_t *socket = (ssl_socket_t *) socket_;
221-
return avs_net_socket_shutdown(socket->backend_socket);
221+
if (socket->backend_socket) {
222+
return avs_net_socket_shutdown(socket->backend_socket);
223+
} else {
224+
return avs_errno(AVS_EBADF);
225+
}
222226
}
223227

224228
static avs_error_t close_ssl(avs_net_socket_t *socket_) {
@@ -232,47 +236,72 @@ static avs_error_t
232236
interface_name_ssl(avs_net_socket_t *ssl_socket_,
233237
avs_net_socket_interface_name_t *if_name) {
234238
ssl_socket_t *ssl_socket = (ssl_socket_t *) ssl_socket_;
235-
return avs_net_socket_interface_name(ssl_socket->backend_socket, if_name);
239+
if (ssl_socket->backend_socket) {
240+
return avs_net_socket_interface_name(ssl_socket->backend_socket,
241+
if_name);
242+
} else {
243+
return avs_errno(AVS_EBADF);
244+
}
236245
}
237246

238247
static avs_error_t remote_host_ssl(avs_net_socket_t *socket_,
239248
char *out_buffer,
240249
size_t out_buffer_size) {
241250
ssl_socket_t *socket = (ssl_socket_t *) socket_;
242-
return avs_net_socket_get_remote_host(socket->backend_socket, out_buffer,
243-
out_buffer_size);
251+
if (socket->backend_socket) {
252+
return avs_net_socket_get_remote_host(socket->backend_socket,
253+
out_buffer, out_buffer_size);
254+
} else {
255+
return avs_errno(AVS_EBADF);
256+
}
244257
}
245258

246259
static avs_error_t remote_hostname_ssl(avs_net_socket_t *socket_,
247260
char *out_buffer,
248261
size_t out_buffer_size) {
249262
ssl_socket_t *socket = (ssl_socket_t *) socket_;
250-
return avs_net_socket_get_remote_hostname(socket->backend_socket,
251-
out_buffer, out_buffer_size);
263+
if (socket->backend_socket) {
264+
return avs_net_socket_get_remote_hostname(socket->backend_socket,
265+
out_buffer, out_buffer_size);
266+
} else {
267+
return avs_errno(AVS_EBADF);
268+
}
252269
}
253270

254271
static avs_error_t remote_port_ssl(avs_net_socket_t *socket_,
255272
char *out_buffer,
256273
size_t out_buffer_size) {
257274
ssl_socket_t *socket = (ssl_socket_t *) socket_;
258-
return avs_net_socket_get_remote_port(socket->backend_socket, out_buffer,
259-
out_buffer_size);
275+
if (socket->backend_socket) {
276+
return avs_net_socket_get_remote_port(socket->backend_socket,
277+
out_buffer, out_buffer_size);
278+
} else {
279+
return avs_errno(AVS_EBADF);
280+
}
260281
}
261282

262283
static avs_error_t local_host_ssl(avs_net_socket_t *socket_,
263284
char *out_buffer,
264285
size_t out_buffer_size) {
265286
ssl_socket_t *socket = (ssl_socket_t *) socket_;
266-
return avs_net_socket_get_local_host(socket->backend_socket, out_buffer,
267-
out_buffer_size);
287+
if (socket->backend_socket) {
288+
return avs_net_socket_get_local_host(socket->backend_socket, out_buffer,
289+
out_buffer_size);
290+
} else {
291+
return avs_errno(AVS_EBADF);
292+
}
268293
}
269294

270295
static avs_error_t local_port_ssl(avs_net_socket_t *socket_,
271296
char *out_buffer,
272297
size_t out_buffer_size) {
273298
ssl_socket_t *socket = (ssl_socket_t *) socket_;
274-
return avs_net_socket_get_local_port(socket->backend_socket, out_buffer,
275-
out_buffer_size);
299+
if (socket->backend_socket) {
300+
return avs_net_socket_get_local_port(socket->backend_socket, out_buffer,
301+
out_buffer_size);
302+
} else {
303+
return avs_errno(AVS_EBADF);
304+
}
276305
}
277306

278307
static int get_socket_inner_mtu_or_zero(avs_net_socket_t *sock) {
@@ -413,6 +442,9 @@ static avs_error_t get_opt_ssl(avs_net_socket_t *ssl_socket_,
413442
if (has_buffered_data(ssl_socket)) {
414443
out_option_value->flag = true;
415444
return AVS_OK;
445+
} else if (!ssl_socket->backend_socket) {
446+
out_option_value->flag = false;
447+
return AVS_OK;
416448
} else {
417449
return avs_net_socket_get_opt(ssl_socket->backend_socket,
418450
AVS_NET_SOCKET_HAS_BUFFERED_DATA,

src/net/compat/posix/avs_net_impl.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,17 @@
2323

2424
# include <avs_commons_posix_init.h>
2525

26-
# include <errno.h>
26+
// Some libraries, like lwIP, define their own errno.h-like header with own
27+
// error macro mappings and definition of errno macro/symbol. This allows for
28+
// including such headers in AVS_COMMONS_POSIX_COMPAT_HEADER and prevents from
29+
// including errno.h defined by standard library.
30+
//
31+
// Note: It might seem more appropriate to write #ifndef errno, but ISO C seems
32+
// to allow to errno to be not only a macro, but also an external linkage symbol
33+
// and lwIP does just that.
34+
# ifndef EDOM
35+
# include <errno.h>
36+
# endif // EDOM
2737

2838
# include <avsystem/commons/avs_errno_map.h>
2939

src/net/mbedtls/avs_mbedtls_socket.c

Lines changed: 16 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,11 @@ avs_bio_recv(void *ctx, unsigned char *buf, size_t len, uint32_t timeout_ms) {
227227
avs_net_socket_opt_value_t new_timeout;
228228
size_t read_bytes;
229229
int result;
230-
if (avs_is_err((socket->bio_error = avs_net_socket_get_opt(
231-
socket->backend_socket,
232-
AVS_NET_SOCKET_OPT_RECV_TIMEOUT,
233-
&orig_timeout)))) {
230+
if (!socket->backend_socket
231+
|| avs_is_err((socket->bio_error = avs_net_socket_get_opt(
232+
socket->backend_socket,
233+
AVS_NET_SOCKET_OPT_RECV_TIMEOUT,
234+
&orig_timeout)))) {
234235
return MBEDTLS_ERR_NET_RECV_FAILED;
235236
}
236237
new_timeout = orig_timeout;
@@ -258,8 +259,9 @@ avs_bio_recv(void *ctx, unsigned char *buf, size_t len, uint32_t timeout_ms) {
258259

259260
static int avs_bio_send(void *ctx, const unsigned char *buf, size_t len) {
260261
ssl_socket_t *socket = (ssl_socket_t *) ctx;
261-
if (avs_is_err((socket->bio_error = avs_net_socket_send(
262-
socket->backend_socket, buf, len)))) {
262+
if (!socket->backend_socket
263+
|| avs_is_err((socket->bio_error = avs_net_socket_send(
264+
socket->backend_socket, buf, len)))) {
263265
return MBEDTLS_ERR_NET_SEND_FAILED;
264266
} else {
265267
return (int) len;
@@ -850,65 +852,24 @@ rng_function(void *ctx, unsigned char *out_buf, size_t out_buf_size) {
850852
}
851853

852854
# ifdef AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE
853-
# ifdef MBEDTLS_SSL_SRV_C
854855
static int fake_session_cache_set(void *socket_,
855-
# if MBEDTLS_VERSION_NUMBER >= 0x03000000
856+
# if MBEDTLS_VERSION_NUMBER >= 0x03000000
856857
unsigned char const *session_id,
857858
size_t session_id_len,
858-
# endif // MBEDTLS_VERSION_NUMBER >= 0x03000000
859+
# endif // MBEDTLS_VERSION_NUMBER >= 0x03000000
859860
const mbedtls_ssl_session *session) {
860861
ssl_socket_t *socket = (ssl_socket_t *) socket_;
861-
# if MBEDTLS_VERSION_NUMBER >= 0x03000000
862+
# if MBEDTLS_VERSION_NUMBER >= 0x03000000
862863
(void) session_id;
863864
(void) session_id_len;
864-
# endif // MBEDTLS_VERSION_NUMBER >= 0x03000000
865+
# endif // MBEDTLS_VERSION_NUMBER >= 0x03000000
865866
(void) session;
866867
// This will be called only if a new session has been established;
867868
// not if one has been resumed.
868869
socket->flags.session_fresh = true;
869870
return 0;
870871
}
871-
# else // MBEDTLS_SSL_SRV_C
872-
# if MBEDTLS_VERSION_NUMBER >= 0x03000000
873-
# error "TLS session persistence is only supported with Mbed TLS >=3.0 if MBEDTLS_SSL_SRV_C is enabled"
874-
# endif // MBEDTLS_VERSION_NUMBER >= 0x03000000
875-
typedef struct {
876-
# ifdef MBEDTLS_HAVE_TIME
877-
mbedtls_time_t start;
878-
# endif // MBEDTLS_HAVE_TIME
879-
int ciphersuite;
880-
int compression;
881-
size_t id_len;
882-
unsigned char id[sizeof(((mbedtls_ssl_session *) NULL)->id)];
883-
} resumed_session_data_t;
884-
885-
static void session_copy(resumed_session_data_t *dest,
886-
const mbedtls_ssl_session *src) {
887-
# ifdef MBEDTLS_HAVE_TIME
888-
dest->start = src->start;
889-
# endif // MBEDTLS_HAVE_TIME
890-
dest->ciphersuite = src->ciphersuite;
891-
dest->compression = src->compression;
892-
dest->id_len = src->id_len;
893-
assert(dest->id_len <= sizeof(dest->id));
894-
memcpy(dest->id, src->id, dest->id_len);
895-
}
896-
897-
static bool sessions_equal(const mbedtls_ssl_session *left,
898-
const resumed_session_data_t *right) {
899-
if (!left && !right) {
900-
return true;
901-
}
902-
return left && right && left->ciphersuite == right->ciphersuite
903-
&& left->compression == right->compression
904-
# ifdef MBEDTLS_HAVE_TIME
905-
&& left->start == right->start
906-
# endif // MBEDTLS_HAVE_TIME
907-
&& left->id_len == right->id_len
908-
&& memcmp(left->id, right->id, left->id_len) == 0;
909-
}
910-
# endif // MBEDTLS_SSL_SRV_C
911-
# endif // AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE
872+
# endif // AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE
912873

913874
static int socket_set_dtls_handshake_timeouts(
914875
ssl_socket_t *socket,
@@ -1017,16 +978,14 @@ configure_ssl(ssl_socket_t *socket,
1017978
}
1018979
# endif // MBEDTLS_SSL_DTLS_CONNECTION_ID
1019980

1020-
# if defined(AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE) \
1021-
&& defined(MBEDTLS_SSL_SRV_C)
981+
# ifdef AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE
1022982
// This is a hack. Session cache is normally used only for server-side TLS.
1023983
// We (ab)use this mechanism on the client side, taking advantage of the
1024984
// fact that Mbed TLS calls it if, and only if, a fresh session has been
1025985
// established, to determine session freshness if resuption is attempted.
1026986
mbedtls_ssl_conf_session_cache(&socket->config, socket, NULL,
1027987
fake_session_cache_set);
1028-
# endif // defined(AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE) &&
1029-
// defined(MBEDTLS_SSL_SRV_C)
988+
# endif // AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE
1030989

1031990
avs_free(socket->effective_ciphersuites);
1032991
if (!(socket->effective_ciphersuites =
@@ -1194,14 +1153,7 @@ static avs_error_t start_ssl(ssl_socket_t *socket, const char *host) {
11941153
socket->flags.session_fresh = false;
11951154
}
11961155
}
1197-
# ifndef MBEDTLS_SSL_SRV_C
1198-
resumed_session_data_t restored_session;
1199-
memset(&restored_session, 0, sizeof(restored_session));
1200-
if (!socket->flags.session_fresh && get_context(socket)->session) {
1201-
session_copy(&restored_session, get_context(socket)->session);
1202-
}
1203-
# endif // MBEDTLS_SSL_SRV_C
1204-
# endif // AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE
1156+
# endif // AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE
12051157
# if defined(MBEDTLS_SSL_PROTO_DTLS)
12061158
if (transport_for_socket_type(socket->backend_type)
12071159
== MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
@@ -1280,13 +1232,6 @@ static avs_error_t start_ssl(ssl_socket_t *socket, const char *host) {
12801232
# endif // defined(AVS_COMMONS_WITH_INTERNAL_LOGS) &&
12811233
// defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
12821234
# ifdef AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE
1283-
# ifndef MBEDTLS_SSL_SRV_C
1284-
if (!socket->flags.session_fresh
1285-
&& !sessions_equal(get_context(socket)->session,
1286-
&restored_session)) {
1287-
socket->flags.session_fresh = true;
1288-
}
1289-
# endif // MBEDTLS_SSL_SRV_C
12901235
if (socket->flags.session_fresh) {
12911236
// We rely on session renegotation being disabled in
12921237
// configuration.

0 commit comments

Comments
 (0)