From b641f7c556e7de6bde95f9fcc0042b924adf42a0 Mon Sep 17 00:00:00 2001
From: Jona <jdemeyer@hotmail.com>
Date: Thu, 18 Feb 2021 21:45:57 +0100
Subject: [PATCH] Discussion basis to write the SNI for MQTTS

SNI (Server Name Indication) is mandatory for AWS IoT:
https://docs.aws.amazon.com/iot/latest/developerguide/transport-security.html
---
 contrib/examples/mqtt/mqtt_example.c   |  6 +++---
 src/apps/altcp_tls/altcp_tls_mbedtls.c | 15 ++++++++++++---
 src/apps/mqtt/mqtt.c                   |  7 ++++---
 src/core/altcp_alloc.c                 |  4 ++--
 src/include/lwip/apps/mqtt.h           |  7 ++++++-
 5 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/contrib/examples/mqtt/mqtt_example.c b/contrib/examples/mqtt/mqtt_example.c
index bb277d6f..fd13be55 100644
--- a/contrib/examples/mqtt/mqtt_example.c
+++ b/contrib/examples/mqtt/mqtt_example.c
@@ -37,14 +37,14 @@
  */
 #ifndef LWIP_MQTT_EXAMPLE_IPADDR_INIT
 #if LWIP_IPV4
-#define LWIP_MQTT_EXAMPLE_IPADDR_INIT = IPADDR4_INIT(PP_HTONL(IPADDR_LOOPBACK))
+#define LWIP_MQTT_EXAMPLE_IPADDR_INIT IPADDR4_INIT(PP_HTONL(IPADDR_LOOPBACK))
 #else
 #define LWIP_MQTT_EXAMPLE_IPADDR_INIT
 #endif
 #endif
 
-static ip_addr_t mqtt_ip LWIP_MQTT_EXAMPLE_IPADDR_INIT;
 static mqtt_client_t* mqtt_client;
+static mqtt_broker_info_t mqtt_broker_info = {LWIP_MQTT_EXAMPLE_IPADDR_INIT, NULL};
 
 static const struct mqtt_connect_client_info_t mqtt_client_info =
 {
@@ -121,7 +121,7 @@ mqtt_example_init(void)
           LWIP_CONST_CAST(void*, &mqtt_client_info));
 
   mqtt_client_connect(mqtt_client,
-          &mqtt_ip, MQTT_PORT,
+          &mqtt_broker_info, MQTT_PORT,
           mqtt_connection_cb, LWIP_CONST_CAST(void*, &mqtt_client_info),
           &mqtt_client_info);
 #endif /* LWIP_TCP */
diff --git a/src/apps/altcp_tls/altcp_tls_mbedtls.c b/src/apps/altcp_tls/altcp_tls_mbedtls.c
index 9956d167..683f7aaf 100644
--- a/src/apps/altcp_tls/altcp_tls_mbedtls.c
+++ b/src/apps/altcp_tls/altcp_tls_mbedtls.c
@@ -603,7 +603,7 @@ altcp_mbedtls_setup_callbacks(struct altcp_pcb *conn, struct altcp_pcb *inner_co
 }
 
 static err_t
-altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn)
+altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn, char *endpoint)
 {
   int ret;
   struct altcp_tls_config *config = (struct altcp_tls_config *)conf;
@@ -627,6 +627,15 @@ altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_
     altcp_mbedtls_free(conf, state);
     return ERR_MEM;
   }
+
+  if (endpoint != NULL)
+  {
+    if ((ret = mbedtls_ssl_set_hostname(&state->ssl_context, endpoint)) != 0)
+    {
+      LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_set_hostname failed\n"));
+    }
+  }
+
   /* tell mbedtls about our I/O functions */
   mbedtls_ssl_set_bio(&state->ssl_context, conn, altcp_mbedtls_bio_send, altcp_mbedtls_bio_recv, NULL);
 
@@ -638,7 +647,7 @@ altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_
 }
 
 struct altcp_pcb *
-altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb)
+altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb, char *endpoint)
 {
   struct altcp_pcb *ret;
   if (inner_pcb == NULL) {
@@ -646,7 +655,7 @@ altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb)
   }
   ret = altcp_alloc();
   if (ret != NULL) {
-    if (altcp_mbedtls_setup(config, ret, inner_pcb) != ERR_OK) {
+    if (altcp_mbedtls_setup(config, ret, inner_pcb, endpoint) != ERR_OK) {
       altcp_free(ret);
       return NULL;
     }
diff --git a/src/apps/mqtt/mqtt.c b/src/apps/mqtt/mqtt.c
index 153cf746..d663db78 100644
--- a/src/apps/mqtt/mqtt.c
+++ b/src/apps/mqtt/mqtt.c
@@ -1277,7 +1277,7 @@ mqtt_client_free(mqtt_client_t *client)
  * @ingroup mqtt
  * Connect to MQTT server
  * @param client MQTT client
- * @param ip_addr Server IP
+ * @param broker_info Structure containing Server IP and Endpoint
  * @param port Server port
  * @param cb Connection state change callback
  * @param arg User supplied argument to connection callback
@@ -1285,7 +1285,7 @@ mqtt_client_free(mqtt_client_t *client)
  * @return ERR_OK if successful, @see err_t enum for other results
  */
 err_t
-mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port, mqtt_connection_cb_t cb, void *arg,
+mqtt_client_connect(mqtt_client_t *client, mqtt_broker_info_t *broker_info, u16_t port, mqtt_connection_cb_t cb, void *arg,
                     const struct mqtt_connect_client_info_t *client_info)
 {
   err_t err;
@@ -1295,6 +1295,7 @@ mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port,
   u16_t remaining_length = 2 + 4 + 1 + 1 + 2;
   u8_t flags = 0, will_topic_len = 0, will_msg_len = 0;
   u16_t client_user_len = 0, client_pass_len = 0;
+  const ip_addr_t *ip_addr = &broker_info->ip_addr;
 
   LWIP_ASSERT_CORE_LOCKED();
   LWIP_ASSERT("mqtt_client_connect: client != NULL", client != NULL);
@@ -1369,7 +1370,7 @@ mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port,
 
 #if LWIP_ALTCP && LWIP_ALTCP_TLS
   if (client_info->tls_config) {
-    client->conn = altcp_tls_new(client_info->tls_config, IP_GET_TYPE(ip_addr));
+    client->conn = altcp_tls_new(client_info->tls_config, IP_GET_TYPE(ip_addr), broker_info->endpoint);
   } else
 #endif
   {
diff --git a/src/core/altcp_alloc.c b/src/core/altcp_alloc.c
index 06ed90d9..addb5649 100644
--- a/src/core/altcp_alloc.c
+++ b/src/core/altcp_alloc.c
@@ -58,7 +58,7 @@
 /** This standard allocator function creates an altcp pcb for
  * TLS over TCP */
 struct altcp_pcb *
-altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type)
+altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type, char *endpoint)
 {
   struct altcp_pcb *inner_conn, *ret;
   LWIP_UNUSED_ARG(ip_type);
@@ -67,7 +67,7 @@ altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type)
   if (inner_conn == NULL) {
     return NULL;
   }
-  ret = altcp_tls_wrap(config, inner_conn);
+  ret = altcp_tls_wrap(config, inner_conn, endpoint);
   if (ret == NULL) {
     altcp_close(inner_conn);
   }
diff --git a/src/include/lwip/apps/mqtt.h b/src/include/lwip/apps/mqtt.h
index f099812d..e92fa3cd 100644
--- a/src/include/lwip/apps/mqtt.h
+++ b/src/include/lwip/apps/mqtt.h
@@ -48,6 +48,11 @@ extern "C" {
 
 typedef struct mqtt_client_s mqtt_client_t;
 
+typedef struct {
+  ip_addr_t ip_addr;
+  const char *endpoint;
+} mqtt_broker_info_t;
+
 #if LWIP_ALTCP && LWIP_ALTCP_TLS
 struct altcp_tls_config;
 #endif
@@ -173,7 +178,7 @@ typedef void (*mqtt_incoming_publish_cb_t)(void *arg, const char *topic, u32_t t
 typedef void (*mqtt_request_cb_t)(void *arg, err_t err);
 
 
-err_t mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ipaddr, u16_t port, mqtt_connection_cb_t cb, void *arg,
+err_t mqtt_client_connect(mqtt_client_t *client, mqtt_broker_info_t *broker_info, u16_t port, mqtt_connection_cb_t cb, void *arg,
                    const struct mqtt_connect_client_info_t *client_info);
 
 void mqtt_disconnect(mqtt_client_t *client);
-- 
2.25.1

