@@ -514,6 +514,7 @@ global:
l_tls_start;
l_tls_close;
l_tls_reset;
+ l_tls_set_server_name;
l_tls_set_cacert;
l_tls_set_auth_data;
l_tls_set_version_range;
@@ -31,6 +31,27 @@
#include "cert.h"
#include "tls-private.h"
+static ssize_t tls_server_name_client_write(struct l_tls *tls,
+ uint8_t *buf, size_t len)
+{
+ size_t hlen;
+
+ if (!tls->server_name)
+ return -ENOMSG;
+
+ hlen = strlen(tls->server_name);
+
+ if (len < hlen + 5)
+ return -ENOMEM;
+
+ l_put_be16(hlen + 3, buf);
+ l_put_u8(0, buf + 2);
+ l_put_be16(hlen, buf + 3);
+ memcpy(buf + 5, tls->server_name, hlen);
+
+ return hlen + 5;
+}
+
/* Most extensions are not used when resuming a cached session */
#define SKIP_ON_RESUMPTION() \
do { \
@@ -975,6 +996,13 @@ static bool tls_renegotiation_info_absent(struct l_tls *tls)
}
const struct tls_hello_extension tls_extensions[] = {
+ {
+ "Server Name", "server_name", 0,
+ tls_server_name_client_write,
+ NULL,
+ NULL,
+ NULL, NULL, NULL,
+ },
{
"Supported Groups", "elliptic_curves", 10,
tls_elliptic_curves_client_write,
@@ -217,6 +217,7 @@ struct l_tls {
char **subject_mask;
struct tls_cipher_suite **cipher_suite_pref_list;
+ char *server_name;
struct l_settings *session_settings;
char *session_prefix;
@@ -3420,6 +3420,7 @@ LIB_EXPORT void l_tls_free(struct l_tls *tls)
if (tls->cipher_suite_pref_list != tls_cipher_suite_pref)
l_free(tls->cipher_suite_pref_list);
+ l_free(tls->server_name);
l_free(tls);
}
@@ -3656,6 +3657,17 @@ LIB_EXPORT void l_tls_reset(struct l_tls *tls)
tls->message_buf_len = 0;
}
+LIB_EXPORT bool l_tls_set_server_name(struct l_tls *tls, const char *name)
+{
+ if (!tls)
+ return false;
+
+ l_free(tls->server_name);
+ tls->server_name = l_strdup(name);
+
+ return true;
+}
+
LIB_EXPORT bool l_tls_set_cacert(struct l_tls *tls, struct l_queue *ca_certs)
{
if (tls->ca_certs) {
@@ -103,6 +103,8 @@ void l_tls_write(struct l_tls *tls, const uint8_t *data, size_t len);
/* Submit TLS payload from underlying transport to be decrypted */
void l_tls_handle_rx(struct l_tls *tls, const uint8_t *data, size_t len);
+bool l_tls_set_server_name(struct l_tls *tls, const char *name);
+
/*
* If peer is to be authenticated, supply the CA certificates. On success
* the l_tls object takes ownership of the queue and the individual l_cert