From 2339726097b463d1f63fa50762b1b76647b780e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnim=20L=C3=A4uger?= Date: Tue, 12 Feb 2019 23:10:25 +0100 Subject: [PATCH] mqtt: add ceritificate handling to support server verification and mutual authentication (#2657) * mqtt: add ceritificate handling to support server verification and mutual authentication * remove superfluous include --- components/modules/mqtt.c | 36 +++++++++++++++++++++++++++++++++++- docs/modules/mqtt.md | 7 ++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/components/modules/mqtt.c b/components/modules/mqtt.c index 0c6d2670..19cbad57 100644 --- a/components/modules/mqtt.c +++ b/components/modules/mqtt.c @@ -42,8 +42,11 @@ typedef struct { lua_ref_t subscribed_ok_cb; lua_ref_t unsubscribed_ok_cb; lua_ref_t self; + lua_ref_t cert_pem; + lua_ref_t client_cert_pem; + lua_ref_t client_key_pem; }; - lua_ref_t lua_refs[9]; + lua_ref_t lua_refs[12]; }; } mqtt_context_t; @@ -334,6 +337,10 @@ static int mqtt_connect(lua_State* L) { int reconnect = 0; int port = 1883; int n = 3; + const char * cert_pem = NULL; + const char * client_cert_pem = NULL; + const char * client_key_pem = NULL; + if (lua_isnumber(L, n)) { port = luaL_checknumber(L, n); @@ -343,6 +350,30 @@ static int mqtt_connect(lua_State* L) { if (lua_isnumber(L, n)) { secure = !!luaL_checkinteger(L, n); n++; + + } else { + if (lua_istable(L, n)) { + secure = true; + lua_getfield(L, n, "ca_cert"); + if ((cert_pem = luaL_optstring(L, -1, NULL)) != NULL) { + luaX_set_ref(L, -1, &mqtt_context->cert_pem); + } + lua_pop(L, 1); + // + lua_getfield(L, n, "client_cert"); + if ((client_cert_pem = luaL_optstring(L, -1, NULL)) != NULL) { + luaX_set_ref(L, -1, &mqtt_context->client_cert_pem); + } + lua_pop(L, 1); + // + lua_getfield(L, n, "client_key"); + if ((client_key_pem = luaL_optstring(L, -1, NULL)) != NULL) { + luaX_set_ref(L, -1, &mqtt_context->client_key_pem); + } + lua_pop(L, 1); + // + n++; + } } if (lua_isnumber(L, n)) { @@ -377,6 +408,9 @@ static int mqtt_connect(lua_State* L) { config.port = port; config.disable_auto_reconnect = (reconnect == 0); config.transport = secure ? MQTT_TRANSPORT_OVER_SSL : MQTT_TRANSPORT_OVER_TCP; + config.cert_pem = cert_pem; + config.client_cert_pem = client_cert_pem; + config.client_key_pem = client_key_pem; // create a mqtt client instance mqtt_context->client = esp_mqtt_client_init(&config); diff --git a/docs/modules/mqtt.md b/docs/modules/mqtt.md index 3e5770fd..a7a89a2c 100644 --- a/docs/modules/mqtt.md +++ b/docs/modules/mqtt.md @@ -98,7 +98,12 @@ Connects to the broker specified by the given host, port, and secure options. #### Parameters - `host` host, domain or IP (string) - `port` broker port (number), default 1883 -- `secure` 0/1 for `false`/`true`, default 0. Take note of constraints documented in the [net module](net.md). +- `secure` either an interger with 0/1 for `false`/`true` (default 0), + or a table with optional entries + - `ca_cert` CA certificate data in PEM format for server verify with SSL + - `client_cert` client certificate data in PEM format for SSL mutual authentication + - `client_key` client private key data in PEM format for SSL mutual authentication + Note that *both* `client_cert` and `client_key` have to be provided for mutual authentication. - `autoreconnect` 0/1 for `false`/`true`, default 0. This option is *deprecated*. - `function(client)` callback function for when the connection was established - `function(client, reason)` callback function for when the connection could not be established. No further callbacks should be called.