net: lib: sockets: added ALPN extension option to TLS
Adds the socket option TLS_ALPN_LIST for SOL_TLS sockets Passes the configured alpn list to the mbedtls config on mbedtls init Signed-off-by: Emil Hammarstrom <emil.hammarstrom@assaabloy.com>
This commit is contained in:
parent
a8a92ce592
commit
ec00feef35
@ -119,6 +119,12 @@ struct zsock_pollfd {
|
||||
* - 1 - server
|
||||
*/
|
||||
#define TLS_DTLS_ROLE 6
|
||||
/** Socket option for setting the supported Application Layer Protocols.
|
||||
* It accepts and returns a const char array of NULL terminated strings
|
||||
* representing the supported application layer protocols listed during
|
||||
* the TLS handshake.
|
||||
*/
|
||||
#define TLS_ALPN_LIST 7
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@ -37,6 +37,10 @@ config MBEDTLS_SSL_EXPORT_KEYS
|
||||
bool "Enable support for exporting SSL key block and master secret"
|
||||
depends on MBEDTLS_TLS_VERSION_1_0 || MBEDTLS_TLS_VERSION_1_1 || MBEDTLS_TLS_VERSION_1_2
|
||||
|
||||
config MBEDTLS_SSL_ALPN
|
||||
bool "Enable support for setting the supported Application Layer Protocols"
|
||||
depends on MBEDTLS_TLS_VERSION_1_0 || MBEDTLS_TLS_VERSION_1_1 || MBEDTLS_TLS_VERSION_1_2
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Ciphersuite configuration"
|
||||
|
||||
@ -100,6 +100,15 @@ config NET_SOCKETS_TLS_MAX_CIPHERSUITES
|
||||
By default, all ciphersuites that are available in the system are
|
||||
available to the socket.
|
||||
|
||||
config NET_SOCKETS_TLS_MAX_APP_PROTOCOLS
|
||||
int "Maximum number of supported application layer protocols"
|
||||
default 2
|
||||
depends on NET_SOCKETS_SOCKOPT_TLS && MBEDTLS_SSL_ALPN
|
||||
help
|
||||
This variable sets maximum number of supported application layer
|
||||
protocols over TLS/DTL that can be set explicitly by a socket option.
|
||||
By default, no supported application layer protocol is set.
|
||||
|
||||
config NET_SOCKETS_OFFLOAD
|
||||
bool "Offload Socket APIs [EXPERIMENTAL]"
|
||||
help
|
||||
|
||||
@ -39,6 +39,12 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL);
|
||||
#include "sockets_internal.h"
|
||||
#include "tls_internal.h"
|
||||
|
||||
#if defined(CONFIG_NET_SOCKETS_TLS_MAX_APP_PROTOCOLS)
|
||||
#define ALPN_MAX_PROTOCOLS (CONFIG_NET_SOCKETS_TLS_MAX_APP_PROTOCOLS + 1)
|
||||
#else
|
||||
#define ALPN_MAX_PROTOCOLS 0
|
||||
#endif /* CONFIG_NET_SOCKETS_TLS_MAX_APP_PROTOCOLS */
|
||||
|
||||
static const struct socket_op_vtable tls_sock_fd_op_vtable;
|
||||
|
||||
/** A list of secure tags that TLS context should use. */
|
||||
@ -109,6 +115,11 @@ struct tls_context {
|
||||
|
||||
/** DTLS role, client by default. */
|
||||
int8_t role;
|
||||
|
||||
/** NULL-terminated list of allowed application layer
|
||||
* protocols.
|
||||
*/
|
||||
const char *alpn_list[ALPN_MAX_PROTOCOLS];
|
||||
} options;
|
||||
|
||||
#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS)
|
||||
@ -920,6 +931,16 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MBEDTLS_SSL_ALPN)
|
||||
if (ALPN_MAX_PROTOCOLS && context->options.alpn_list[0] != NULL) {
|
||||
ret = mbedtls_ssl_conf_alpn_protocols(&context->config,
|
||||
context->options.alpn_list);
|
||||
if (ret != 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_MBEDTLS_SSL_ALPN */
|
||||
|
||||
ret = mbedtls_ssl_setup(&context->ssl,
|
||||
&context->config);
|
||||
if (ret != 0) {
|
||||
@ -1072,6 +1093,64 @@ static int tls_opt_ciphersuite_used_get(struct tls_context *context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tls_opt_alpn_list_set(struct tls_context *context,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
int alpn_cnt;
|
||||
|
||||
if (!ALPN_MAX_PROTOCOLS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!optval) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (optlen % sizeof(const char *) != 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
alpn_cnt = optlen / sizeof(const char *);
|
||||
/* + 1 for NULL-termination. */
|
||||
if (alpn_cnt + 1 > ARRAY_SIZE(context->options.alpn_list)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(context->options.alpn_list, optval, optlen);
|
||||
context->options.alpn_list[alpn_cnt] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tls_opt_alpn_list_get(struct tls_context *context,
|
||||
void *optval, socklen_t *optlen)
|
||||
{
|
||||
const char **alpn_list = context->options.alpn_list;
|
||||
int alpn_cnt, i = 0;
|
||||
const char **ret_list = optval;
|
||||
|
||||
if (!ALPN_MAX_PROTOCOLS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (*optlen % sizeof(const char *) != 0 || *optlen == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
alpn_cnt = *optlen / sizeof(const char *);
|
||||
while (alpn_list[i] != NULL) {
|
||||
ret_list[i] = alpn_list[i];
|
||||
|
||||
if (++i == alpn_cnt) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*optlen = i * sizeof(const char *);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tls_opt_peer_verify_set(struct tls_context *context,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
@ -1922,6 +2001,10 @@ int ztls_getsockopt_ctx(struct tls_context *ctx, int level, int optname,
|
||||
err = tls_opt_ciphersuite_used_get(ctx, optval, optlen);
|
||||
break;
|
||||
|
||||
case TLS_ALPN_LIST:
|
||||
err = tls_opt_alpn_list_get(ctx, optval, optlen);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown or write-only option. */
|
||||
err = -ENOPROTOOPT;
|
||||
@ -1967,6 +2050,10 @@ int ztls_setsockopt_ctx(struct tls_context *ctx, int level, int optname,
|
||||
err = tls_opt_dtls_role_set(ctx, optval, optlen);
|
||||
break;
|
||||
|
||||
case TLS_ALPN_LIST:
|
||||
err = tls_opt_alpn_list_set(ctx, optval, optlen);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unknown or read-only option. */
|
||||
err = -ENOPROTOOPT;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user