Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add curl easy socket backend. #380

Merged
merged 9 commits into from
Dec 11, 2023
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,20 @@ Since the broker and subscriber are still running, you can use `mqttclient` to p

Congratulations! You have just published an MQTT message using TLS 1.3 with the `KYBER_LEVEL1` KEM and `FALCON_LEVEL1` signature scheme. To use the hybrid group, replace `KYBER_LEVEL1` with `P256_KYBER_LEVEL1`.


## Curl Easy Socket Support

wolfMQTT now supports using libcurl's easy socket interface as a backend.
When enabled, wolfMQTT will use the libcurl API for the socket backend,
and libcurl will use wolfSSL to negotiate TLS.
This can be enabled with `--enable-curl`.

At this time wolfMQTT's libcurl option supports both TLS and mTLS, but not Post-Quantum TLS.

### How to use libcurl with wolfMQTT

To use wolfMQTT with libcurl and wolfSSL:
- build wolfssl with `--enable-curl` and install to `/usr/local`.
- build libcurl with `--with-wolfssl` and install to `/usr/local`.

Finally, build wolfMQTT with `--enable-curl`.
15 changes: 15 additions & 0 deletions configure.ac
embhorn marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,19 @@ AC_CHECK_LIB([wolfssl],[wolfCrypt_Init],,[AC_MSG_ERROR([libwolfssl is required a

fi

# libcurl support
AC_ARG_ENABLE([curl],
[AS_HELP_STRING([--enable-curl],[Enable curl easy socket backend (default: disabled)])],
[ ENABLED_CURL=$enableval ],
[ ENABLED_CURL=no ]
)

if test "x$ENABLED_CURL" = "xyes"; then
AM_CFLAGS="$AM_CFLAGS -DENABLE_MQTT_CURL"

AC_CHECK_LIB([curl],[curl_easy_init],,[AC_MSG_ERROR([libcurl is required and wasn't found on the system. It can be obtained from https://curl.se/download.html.])])
fi


# Non-Blocking support
AC_ARG_ENABLE([nonblock],
Expand Down Expand Up @@ -310,6 +323,7 @@ fi


AM_CONDITIONAL([HAVE_LIBWOLFSSL], [test "x$ENABLED_TLS" = "xyes"])
AM_CONDITIONAL([HAVE_LIBCURL], [test "x$ENABLED_CURL" = "xyes"])
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$ENABLED_EXAMPLES" = "xyes"])
AM_CONDITIONAL([BUILD_STDINCAP], [test "x$ENABLED_STDINCAP" = "xyes"])
AM_CONDITIONAL([BUILD_SN], [test "x$ENABLED_SN" = "xyes"])
Expand Down Expand Up @@ -440,4 +454,5 @@ echo " * Examples: $ENABLED_EXAMPLES"
echo " * Non-Blocking: $ENABLED_NONBLOCK"
echo " * STDIN Capture: $ENABLED_STDINCAP"
echo " * TLS: $ENABLED_TLS"
echo " * CURL: $ENABLED_CURL"
echo " * Multi-thread: $ENABLED_MULTITHREAD"
5 changes: 3 additions & 2 deletions examples/aws/awsiot.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
#include "wolfmqtt/mqtt_client.h"


/* This example only works with ENABLE_MQTT_TLS (wolfSSL library) */
#if defined(ENABLE_MQTT_TLS)
/* This example only works with ENABLE_MQTT_TLS (wolfSSL library),
* and without ENABLE_MQTT_CURL. */
#if defined(ENABLE_MQTT_TLS) && !defined(ENABLE_MQTT_CURL)
#if !defined(WOLFSSL_USER_SETTINGS) && !defined(USE_WINDOWS_API)
#include <wolfssl/options.h>
#endif
Expand Down
5 changes: 3 additions & 2 deletions examples/azure/azureiothub.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
#include "wolfmqtt/mqtt_client.h"


/* This example only works with ENABLE_MQTT_TLS (wolfSSL library) */
/* This example only works with ENABLE_MQTT_TLS (wolfSSL library)
* and without ENABLE_MQTT_CURL. */
/* Notes:
* The wolfSSL library must be built with
* #define WOLFSSL_BASE64_ENCODE
Expand All @@ -39,7 +40,7 @@
*/

/* This example requires features in wolfSSL 3.9.1 or later */
#if defined(ENABLE_MQTT_TLS)
#if defined(ENABLE_MQTT_TLS) && !defined(ENABLE_MQTT_CURL)
#if !defined(WOLFSSL_USER_SETTINGS) && !defined(USE_WINDOWS_API)
#include <wolfssl/options.h>
#endif
Expand Down
1 change: 1 addition & 0 deletions examples/firmware/fwclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "wolfmqtt/mqtt_client.h"

/* This example only works with ENABLE_MQTT_TLS (wolfSSL library). */
#if defined(ENABLE_MQTT_TLS)
#if !defined(WOLFSSL_USER_SETTINGS) && !defined(USE_WINDOWS_API)
#include <wolfssl/options.h>
Expand Down
79 changes: 48 additions & 31 deletions examples/mqttexample.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,12 @@ static int myoptind = 0;
static char* myoptarg = NULL;

#ifdef ENABLE_MQTT_TLS
static const char* mTlsCaFile;
static const char* mTlsCertFile;
static const char* mTlsKeyFile;
#ifdef HAVE_SNI
static int useSNI;
static const char* mTlsSniHostName;
static const char* mTlsSniHostName = NULL;
#endif
#ifdef HAVE_PQC
static const char* mTlsPQAlg;
static const char* mTlsPQAlg = NULL;
#endif
#endif /* ENABLE_MQTT_TLS */

Expand Down Expand Up @@ -226,16 +223,17 @@ void mqtt_show_usage(MQTTCtx* mqttCtx)
PRINTF("-A <file> Load CA (validate peer)");
PRINTF("-K <key> Use private key (for TLS mutual auth)");
PRINTF("-c <cert> Use certificate (for TLS mutual auth)");
#ifdef HAVE_SNI
#ifndef ENABLE_MQTT_CURL
#ifdef HAVE_SNI
/* Remove SNI args for sn-client */
if(XSTRNCMP(mqttCtx->app_name, "sn-client", 10)){
PRINTF("-S <str> Use Host Name Indication, blank defaults to host");
}
#endif
#ifdef HAVE_PQC
#endif /* HAVE_SNI */
#ifdef HAVE_PQC
PRINTF("-Q <str> Use Key Share with post-quantum algorithm");
#endif
#else
#endif /* HAVE_PQC */
#endif /* !ENABLE_MQTT_CURL */
PRINTF("-p <num> Port to connect on, default: %d",
MQTT_DEFAULT_PORT);
#endif
Expand Down Expand Up @@ -286,6 +284,11 @@ void mqtt_init_ctx(MQTTCtx* mqttCtx)
#endif
#ifdef WOLFMQTT_DEFAULT_TLS
mqttCtx->use_tls = WOLFMQTT_DEFAULT_TLS;
#endif
#ifdef ENABLE_MQTT_TLS
mqttCtx->ca_file = NULL;
mqttCtx->mtls_keyfile = NULL;
mqttCtx->mtls_certfile = NULL;
#endif
mqttCtx->app_name = "mqttclient";
mqttCtx->message = DEFAULT_MESSAGE;
Expand All @@ -296,7 +299,11 @@ int mqtt_parse_args(MQTTCtx* mqttCtx, int argc, char** argv)
int rc;

#ifdef ENABLE_MQTT_TLS
#define MQTT_TLS_ARGS "c:A:K:S;Q:"
#ifdef ENABLE_MQTT_CURL
#define MQTT_TLS_ARGS "c:A:K:"
#else
#define MQTT_TLS_ARGS "c:A:K:S;Q:"
#endif
#else
#define MQTT_TLS_ARGS ""
#endif
Expand Down Expand Up @@ -389,14 +396,15 @@ int mqtt_parse_args(MQTTCtx* mqttCtx, int argc, char** argv)

#ifdef ENABLE_MQTT_TLS
case 'A':
mTlsCaFile = myoptarg;
mqttCtx->ca_file = myoptarg;
break;
case 'c':
mTlsCertFile = myoptarg;
mqttCtx->mtls_certfile = myoptarg;
break;
case 'K':
mTlsKeyFile = myoptarg;
mqttCtx->mtls_keyfile = myoptarg;
break;
#ifndef ENABLE_MQTT_CURL
case 'S':
#ifdef HAVE_SNI
useSNI = 1;
Expand All @@ -412,7 +420,8 @@ int mqtt_parse_args(MQTTCtx* mqttCtx, int argc, char** argv)
PRINTF("To use '-Q', build wolfSSL with --with-liboqs");
#endif
break;
#endif
#endif /* !ENABLE_MQTT_CURL */
#endif /* ENABLE_MQTT_TLS */

#ifdef WOLFMQTT_V5
case 'P':
Expand Down Expand Up @@ -620,6 +629,7 @@ static int mqtt_tls_verify_cb(int preverify, WOLFSSL_X509_STORE_CTX* store)
int mqtt_tls_cb(MqttClient* client)
{
int rc = WOLFSSL_FAILURE;
SocketContext * sock = (SocketContext *)client->net->context;

/* Use highest available and allow downgrade. If wolfSSL is built with
* old TLS support, it is possible for a server to force a downgrade to
Expand All @@ -634,22 +644,22 @@ int mqtt_tls_cb(MqttClient* client)

#if !defined(NO_CERT)
#if !defined(NO_FILESYSTEM)
if (mTlsCaFile) {
if (sock->mqttCtx->ca_file) {
/* Load CA certificate file */
rc = wolfSSL_CTX_load_verify_locations(client->tls.ctx,
mTlsCaFile, NULL);
sock->mqttCtx->ca_file, NULL);
if (rc != WOLFSSL_SUCCESS) {
PRINTF("Error loading CA %s: %d (%s)", mTlsCaFile,
PRINTF("Error loading CA %s: %d (%s)", sock->mqttCtx->ca_file,
rc, wolfSSL_ERR_reason_error_string(rc));
return rc;
}
}
if (mTlsCertFile && mTlsKeyFile) {
if (sock->mqttCtx->mtls_certfile && sock->mqttCtx->mtls_keyfile) {
/* Load If using a mutual authentication */
rc = wolfSSL_CTX_use_certificate_file(client->tls.ctx,
mTlsCertFile, WOLFSSL_FILETYPE_PEM);
sock->mqttCtx->mtls_certfile, WOLFSSL_FILETYPE_PEM);
if (rc != WOLFSSL_SUCCESS) {
PRINTF("Error loading certificate %s: %d (%s)", mTlsCertFile,
PRINTF("Error loading certificate %s: %d (%s)", sock->mqttCtx->mtls_certfile,
rc, wolfSSL_ERR_reason_error_string(rc));
return rc;
}
Expand All @@ -661,9 +671,9 @@ int mqtt_tls_cb(MqttClient* client)
#endif

rc = wolfSSL_CTX_use_PrivateKey_file(client->tls.ctx,
mTlsKeyFile, WOLFSSL_FILETYPE_PEM);
sock->mqttCtx->mtls_keyfile, WOLFSSL_FILETYPE_PEM);
if (rc != WOLFSSL_SUCCESS) {
PRINTF("Error loading key %s: %d (%s)", mTlsKeyFile,
PRINTF("Error loading key %s: %d (%s)", sock->mqttCtx->mtls_keyfile,
rc, wolfSSL_ERR_reason_error_string(rc));
return rc;
}
Expand Down Expand Up @@ -733,6 +743,10 @@ int mqtt_tls_cb(MqttClient* client)
#endif /* HAVE_PQC */
}

#if defined(NO_CERT) || defined(NO_FILESYSTEM)
(void)sock;
#endif

PRINTF("MQTT TLS Setup (%d)", rc);

return rc;
Expand All @@ -742,6 +756,7 @@ int mqtt_tls_cb(MqttClient* client)
int mqtt_dtls_cb(MqttClient* client) {
#ifdef WOLFSSL_DTLS
int rc = WOLFSSL_FAILURE;
SocketContext * sock = (SocketContext *)client->net->context;

client->tls.ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
if (client->tls.ctx) {
Expand All @@ -752,34 +767,36 @@ int mqtt_dtls_cb(MqttClient* client) {
rc = WOLFSSL_SUCCESS;

#if !defined(NO_CERT) && !defined(NO_FILESYSTEM)
if (mTlsCaFile) {
if (sock->mqttCtx->ca_file) {
/* Load CA certificate file */
rc = wolfSSL_CTX_load_verify_locations(client->tls.ctx,
mTlsCaFile, NULL);
sock->mqttCtx->ca_file, NULL);
if (rc != WOLFSSL_SUCCESS) {
PRINTF("Error loading CA %s: %d (%s)", mTlsCaFile,
PRINTF("Error loading CA %s: %d (%s)", sock->mqttCtx->ca_file,
rc, wolfSSL_ERR_reason_error_string(rc));
return rc;
}
}
if (mTlsCertFile && mTlsKeyFile) {
if (sock->mqttCtx->mtls_certfile && sock->mqttCtx->mtls_keyfile) {
/* Load If using a mutual authentication */
rc = wolfSSL_CTX_use_certificate_file(client->tls.ctx,
mTlsCertFile, WOLFSSL_FILETYPE_PEM);
sock->mqttCtx->mtls_certfile, WOLFSSL_FILETYPE_PEM);
if (rc != WOLFSSL_SUCCESS) {
PRINTF("Error loading certificate %s: %d (%s)", mTlsCertFile,
PRINTF("Error loading certificate %s: %d (%s)", sock->mqttCtx->mtls_certfile,
rc, wolfSSL_ERR_reason_error_string(rc));
return rc;
}

rc = wolfSSL_CTX_use_PrivateKey_file(client->tls.ctx,
mTlsKeyFile, WOLFSSL_FILETYPE_PEM);
sock->mqttCtx->mtls_keyfile, WOLFSSL_FILETYPE_PEM);
if (rc != WOLFSSL_SUCCESS) {
PRINTF("Error loading key %s: %d (%s)", mTlsKeyFile,
PRINTF("Error loading key %s: %d (%s)", sock->mqttCtx->mtls_keyfile,
rc, wolfSSL_ERR_reason_error_string(rc));
return rc;
}
}
#else
(void)sock;
#endif

client->tls.ssl = wolfSSL_new(client->tls.ctx);
Expand Down
5 changes: 5 additions & 0 deletions examples/mqttexample.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ typedef struct _MQTTCtx {
const char* message;
const char* pub_file;
const char* client_id;
#if defined (ENABLE_MQTT_TLS)
const char* ca_file;
const char* mtls_keyfile;
const char* mtls_certfile;
#endif
byte *tx_buf, *rx_buf;
int return_code;
int use_tls;
Expand Down
Loading
Loading