Skip to content

Commit

Permalink
net: sockets: tls: Implement TLS_DTLS_CONNECTION_ID option
Browse files Browse the repository at this point in the history
Implement TLS_DTLS_CONNECTION_ID socket option, which enables to use
Connection ID extension for the DTLS session.

The option allows to set the value and the length of the CID to use with
`setsockopt()` function. Setting the CID length to 0, enables the
extension but does not send the own CID to the peer, as described in the
specification.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
  • Loading branch information
rlubos committed Jul 5, 2021
1 parent e9b2ebe commit f2078a5
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/net/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ struct zsock_pollfd {
*/
#define TLS_DTLS_HANDSHAKE_TIMEOUT_MIN 8
#define TLS_DTLS_HANDSHAKE_TIMEOUT_MAX 9
/** Socket option to set DTLS Connection ID to be used for the DTLS session.
* The option accepts an byte array, holding the CID to use.
* Setting an empty CID (option length set to 0) indicates that the socket is
* willing to handle CID from a peer, but does not specify its own CID.
*/
#define TLS_DTLS_CONNECTION_ID 10

/** @} */

Expand Down
63 changes: 63 additions & 0 deletions subsys/net/lib/sockets/sockets_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL);
#define ALPN_MAX_PROTOCOLS 0
#endif /* CONFIG_NET_SOCKETS_TLS_MAX_APP_PROTOCOLS */

#define DTLS_CONNECTION_ID_DISABLED -1

static const struct socket_op_vtable tls_sock_fd_op_vtable;

/** A list of secure tags that TLS context should use. */
Expand Down Expand Up @@ -123,6 +125,16 @@ __net_socket struct tls_context {
/* DTLS handshake timeout */
uint32_t dtls_handshake_timeout_min;
uint32_t dtls_handshake_timeout_max;

struct {
/** The CID value to use. */
uint8_t value[MBEDTLS_SSL_CID_IN_LEN_MAX];

/** The CID length. -1 indicates that CID extension is
* disabled.
*/
int len;
} dtls_cid;
#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */
} options;

Expand Down Expand Up @@ -365,6 +377,7 @@ static struct tls_context *tls_alloc(void)
MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN;
tls->options.dtls_handshake_timeout_max =
MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX;
tls->options.dtls_cid.len = DTLS_CONNECTION_ID_DISABLED;
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_init(&tls->ca_chain);
Expand Down Expand Up @@ -922,6 +935,18 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server)
context->options.dtls_handshake_timeout_min,
context->options.dtls_handshake_timeout_max);

#if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID)
if (context->options.dtls_cid.len != DTLS_CONNECTION_ID_DISABLED) {
ret = mbedtls_ssl_conf_cid(
&context->config,
context->options.dtls_cid.len,
MBEDTLS_SSL_UNEXPECTED_CID_IGNORE);
if (ret != 0) {
return -EINVAL;
}
}
#endif /* CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID */

/* Configure cookie for DTLS server */
if (role == MBEDTLS_SSL_IS_SERVER) {
ret = mbedtls_ssl_cookie_setup(&context->cookie,
Expand Down Expand Up @@ -989,6 +1014,19 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server)
return -ENOMEM;
}

#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) && defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID)
if (type == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
if (context->options.dtls_cid.len != DTLS_CONNECTION_ID_DISABLED) {
ret = mbedtls_ssl_set_cid(&context->ssl, true,
context->options.dtls_cid.value,
context->options.dtls_cid.len);
if (ret != 0) {
return -EINVAL;
}
}
}
#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS && CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID */

context->is_initialized = true;

return 0;
Expand Down Expand Up @@ -1227,6 +1265,27 @@ static int tls_opt_dtls_handshake_timeout_set(struct tls_context *context,

return 0;
}

static int tls_opt_dtls_connection_id_set(struct tls_context *context,
const void *optval, socklen_t optlen)
{
#if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID)
if (optlen > 0 && optval == NULL) {
return -EINVAL;
}

if (optlen > sizeof(context->options.dtls_cid.value)) {
return -EINVAL;
}

context->options.dtls_cid.len = optlen;
memcpy(context->options.dtls_cid.value, optval, optlen);

return 0;
#else
return -ENOPROTOOPT;
#endif /* CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID */
}
#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */

static int tls_opt_alpn_list_get(struct tls_context *context,
Expand Down Expand Up @@ -2330,6 +2389,10 @@ int ztls_setsockopt_ctx(struct tls_context *ctx, int level, int optname,
err = tls_opt_dtls_handshake_timeout_set(ctx, optval,
optlen, true);
break;

case TLS_DTLS_CONNECTION_ID:
err = tls_opt_dtls_connection_id_set(ctx, optval, optlen);
break;
#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */

default:
Expand Down

0 comments on commit f2078a5

Please sign in to comment.