diff --git a/CMakeLists.txt b/CMakeLists.txt index 1148e8ed7..b713499d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ SET(PAHO_ENABLE_TESTING TRUE CACHE BOOL "Build tests and run") SET(PAHO_ENABLE_CPACK TRUE CACHE BOOL "Enable CPack") SET(PAHO_HIGH_PERFORMANCE FALSE CACHE BOOL "Disable tracing and heap tracking") SET(PAHO_USE_SELECT FALSE CACHE BOOL "Revert to select system call instead of poll") +SET(PAHO_WITH_SSL_ENGINE FALSE CACHE BOOL "Enable usage of OpenSSL engines") IF (PAHO_HIGH_PERFORMANCE) ADD_DEFINITIONS(-DHIGH_PERFORMANCE=1) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f795b9a4..d995e8afe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -199,16 +199,28 @@ IF (PAHO_WITH_SSL) ADD_LIBRARY(common_ssl_obj OBJECT ${common_src}) TARGET_INCLUDE_DIRECTORIES(common_ssl_obj PUBLIC ${OPENSSL_INCLUDE_DIR}) SET_PROPERTY(TARGET common_ssl_obj PROPERTY POSITION_INDEPENDENT_CODE ON) - SET_PROPERTY(TARGET common_ssl_obj PROPERTY COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1") - + IF (PAHO_WITH_SSL_ENGINE) + SET_PROPERTY(TARGET common_ssl_obj PROPERTY COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1;OPENSSL_ENGINE=1") + ELSE() + SET_PROPERTY(TARGET common_ssl_obj PROPERTY COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1") + ENDIF() + ADD_LIBRARY(paho-mqtt3cs SHARED $ MQTTClient.c SSLSocket.c) ADD_LIBRARY(paho-mqtt3as SHARED $ MQTTAsync.c MQTTAsyncUtils.c SSLSocket.c) - - SET_TARGET_PROPERTIES( - paho-mqtt3cs paho-mqtt3as PROPERTIES - VERSION ${CLIENT_VERSION} - SOVERSION ${PAHO_VERSION_MAJOR} - COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1") + + IF (PAHO_WITH_SSL_ENGINE) + SET_TARGET_PROPERTIES( + paho-mqtt3cs paho-mqtt3as PROPERTIES + VERSION ${CLIENT_VERSION} + SOVERSION ${PAHO_VERSION_MAJOR} + COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1;OPENSSL_ENGINE=1") + ELSE() + SET_TARGET_PROPERTIES( + paho-mqtt3cs paho-mqtt3as PROPERTIES + VERSION ${CLIENT_VERSION} + SOVERSION ${PAHO_VERSION_MAJOR} + COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1") + ENDIF() IF(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") SET(MQTTCLIENT_ENTRY_POINT _MQTTClient_init) @@ -251,16 +263,29 @@ IF (PAHO_WITH_SSL) ADD_LIBRARY(common_ssl_obj_static OBJECT ${common_src}) TARGET_INCLUDE_DIRECTORIES(common_ssl_obj_static PUBLIC ${OPENSSL_INCLUDE_DIR}) SET_PROPERTY(TARGET common_ssl_obj_static PROPERTY POSITION_INDEPENDENT_CODE ON) - SET_PROPERTY(TARGET common_ssl_obj_static PROPERTY COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_STATIC=1") - + IF (PAHO_WITH_SSL_ENGINE) + SET_PROPERTY(TARGET common_ssl_obj_static PROPERTY COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1;OPENSSL_ENGINE=1") + ELSE() + SET_PROPERTY(TARGET common_ssl_obj_static PROPERTY COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1") + ENDIF() + ADD_LIBRARY(paho-mqtt3cs-static STATIC $ MQTTClient.c SSLSocket.c) ADD_LIBRARY(paho-mqtt3as-static STATIC $ MQTTAsync.c MQTTAsyncUtils.c SSLSocket.c) - SET_TARGET_PROPERTIES( - paho-mqtt3cs-static paho-mqtt3as-static PROPERTIES - VERSION ${CLIENT_VERSION} - SOVERSION ${PAHO_VERSION_MAJOR} - COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_STATIC=1") + IF (PAHO_WITH_SSL_ENGINE) + SET_TARGET_PROPERTIES( + paho-mqtt3cs-static paho-mqtt3as-static PROPERTIES + VERSION ${CLIENT_VERSION} + SOVERSION ${PAHO_VERSION_MAJOR} + COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1;OPENSSL_ENGINE=1") + ELSE() + SET_TARGET_PROPERTIES( + paho-mqtt3cs-static paho-mqtt3as-static PROPERTIES + VERSION ${CLIENT_VERSION} + SOVERSION ${PAHO_VERSION_MAJOR} + COMPILE_DEFINITIONS "OPENSSL=1;PAHO_MQTT_EXPORTS=1") + ENDIF() + IF (NOT WIN32) SET_TARGET_PROPERTIES(paho-mqtt3cs-static PROPERTIES OUTPUT_NAME paho-mqtt3cs) SET_TARGET_PROPERTIES(paho-mqtt3as-static PROPERTIES OUTPUT_NAME paho-mqtt3as) diff --git a/src/Clients.h b/src/Clients.h index 674895821..508179890 100644 --- a/src/Clients.h +++ b/src/Clients.h @@ -3,11 +3,11 @@ * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. + * and Eclipse Distribution License v1.0 which accompany this distribution. * - * The Eclipse Public License is available at + * The Eclipse Public License is available at * https://www.eclipse.org/legal/epl-2.0/ - * and the Eclipse Distribution License is available at + * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: @@ -29,6 +29,7 @@ #endif #if defined(OPENSSL) #include +#include #endif #include "MQTTClient.h" #include "LinkedList.h" @@ -87,6 +88,13 @@ typedef struct SSL_CTX* ctx; char *https_proxy; char *https_proxy_auth; + +#if defined(OPENSSL_ENGINE) + // Engine values. + ENGINE *engine; + char using_engine; +#endif // OPENSSL_ENGINE + #endif char *http_proxy; char *http_proxy_auth; diff --git a/src/MQTTAsync.c b/src/MQTTAsync.c index c6a11f6d3..328ec4c2b 100644 --- a/src/MQTTAsync.c +++ b/src/MQTTAsync.c @@ -753,6 +753,8 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options) free((void*)m->c->sslopts->privateKeyPassword); if (m->c->sslopts->enabledCipherSuites) free((void*)m->c->sslopts->enabledCipherSuites); + if (m->c->sslopts->engine) + free((void*)m->c->sslopts->engine); if (m->c->sslopts->struct_version >= 2) { if (m->c->sslopts->CApath) @@ -781,6 +783,8 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options) m->c->sslopts->privateKeyPassword = MQTTStrdup(options->ssl->privateKeyPassword); if (options->ssl->enabledCipherSuites) m->c->sslopts->enabledCipherSuites = MQTTStrdup(options->ssl->enabledCipherSuites); + if (options->ssl->engine) + m->c->sslopts->engine = MQTTStrdup(options->ssl->engine); m->c->sslopts->enableServerCertAuth = options->ssl->enableServerCertAuth; if (m->c->sslopts->struct_version >= 1) m->c->sslopts->sslVersion = options->ssl->sslVersion; diff --git a/src/MQTTAsync.h b/src/MQTTAsync.h index e11af0482..7d43ade33 100644 --- a/src/MQTTAsync.h +++ b/src/MQTTAsync.h @@ -489,7 +489,7 @@ typedef struct #define MQTTAsync_connectData_initializer {{'M', 'Q', 'C', 'D'}, 0, NULL, {0, NULL}} /** - * This is a callback function which will allow the client application to update the + * This is a callback function which will allow the client application to update the * connection data. * @param data The connection data which can be modified by the application. * @return Return a non-zero value to update the connect data, zero to keep the same data. @@ -1174,6 +1174,11 @@ typedef struct * Exists only if struct_version >= 5 */ unsigned int protos_len; + + /** + * The name of the OpenSSL engine that we should use. + */ + char *engine; } MQTTAsync_SSLOptions; #define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } diff --git a/src/MQTTClient.c b/src/MQTTClient.c index b6a7714b7..eb226b6f9 100644 --- a/src/MQTTClient.c +++ b/src/MQTTClient.c @@ -1595,6 +1595,8 @@ static MQTTResponse MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectO free((void*)m->c->sslopts->privateKeyPassword); if (m->c->sslopts->enabledCipherSuites) free((void*)m->c->sslopts->enabledCipherSuites); + if (m->c->sslopts->engine) + free((void*)m->c->sslopts->engine); if (m->c->sslopts->struct_version >= 2) { if (m->c->sslopts->CApath) @@ -1623,6 +1625,8 @@ static MQTTResponse MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectO m->c->sslopts->privateKeyPassword = MQTTStrdup(options->ssl->privateKeyPassword); if (options->ssl->enabledCipherSuites) m->c->sslopts->enabledCipherSuites = MQTTStrdup(options->ssl->enabledCipherSuites); + if (options->ssl->engine) + m->c->sslopts->engine = MQTTStrdup(options->ssl->engine); m->c->sslopts->enableServerCertAuth = options->ssl->enableServerCertAuth; if (m->c->sslopts->struct_version >= 1) m->c->sslopts->sslVersion = options->ssl->sslVersion; diff --git a/src/MQTTClient.h b/src/MQTTClient.h index a5dc7f267..52e805000 100644 --- a/src/MQTTClient.h +++ b/src/MQTTClient.h @@ -777,9 +777,14 @@ typedef struct * Exists only if struct_version >= 5 */ unsigned int protos_len; + + /** + * The OpenSSL engine name that we should laod. + */ + char* engine; } MQTTClient_SSLOptions; -#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 } +#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, NULL } /** * MQTTClient_libraryInfo is used to store details relating to the currently used diff --git a/src/MQTTProtocolClient.c b/src/MQTTProtocolClient.c index e4b8f16c7..11489caf4 100644 --- a/src/MQTTProtocolClient.c +++ b/src/MQTTProtocolClient.c @@ -345,7 +345,7 @@ int MQTTProtocol_handlePublishes(void* pack, SOCKET sock) if (publish->header.bits.qos == 1) { Protocol_processPublication(publish, client, 1); - + if (socketHasPendingWrites) rc = MQTTProtocol_queueAck(client, PUBACK, publish->msgId); else @@ -971,6 +971,8 @@ void MQTTProtocol_freeClient(Clients* client) free((void*)client->sslopts->privateKeyPassword); if (client->sslopts->enabledCipherSuites) free((void*)client->sslopts->enabledCipherSuites); + if (client->sslopts->engine) + free((void*)client->sslopts->engine); if (client->sslopts->struct_version >= 2) { if (client->sslopts->CApath) @@ -982,7 +984,7 @@ void MQTTProtocol_freeClient(Clients* client) free((void*)client->sslopts->protos); } free(client->sslopts); - client->sslopts = NULL; + client->sslopts = NULL; } #endif /* don't free the client structure itself... this is done elsewhere */ diff --git a/src/SSLSocket.c b/src/SSLSocket.c index a4941b60c..ce9787a6d 100644 --- a/src/SSLSocket.c +++ b/src/SSLSocket.c @@ -44,6 +44,11 @@ #include #include +#if defined(OPENSSL_ENGINE) +// Use an engine. +#include +#endif + extern Sockets mod_s; static int SSLSocket_error(char* aString, SSL* ssl, SOCKET sock, int rc, int (*cb)(const char *str, size_t len, void *u), void* u); @@ -462,6 +467,11 @@ int SSLSocket_initialize(void) OpenSSL_add_all_algorithms(); +#if defined(OPENSSL_ENGINE) + Log(LOG_PROTOCOL, -1, "Loading built-in engines..."); + ENGINE_load_builtin_engines(); +#endif + lockMemSize = CRYPTO_num_locks() * sizeof(ssl_mutex_type); sslLocks = malloc(lockMemSize); @@ -484,7 +494,6 @@ int SSLSocket_initialize(void) CRYPTO_set_id_callback(SSLThread_id); #endif CRYPTO_set_locking_callback(SSLLocks_callback); - } SSL_create_mutex(&sslCoreMutex); @@ -505,6 +514,12 @@ void SSLSocket_terminate(void) CRYPTO_set_locking_callback(NULL); ERR_free_strings(); EVP_cleanup(); + +#if defined(OPENSSL_ENGINE) + Log(LOG_PROTOCOL, -1, "Cleaning up engine..."); + ENGINE_cleanup(); +#endif + if (sslLocks) { int i = 0; @@ -547,9 +562,18 @@ int SSLSocket_createContext(networkHandles* net, MQTTClient_SSLOptions* opts) { int rc = 1; +#if defined(OPENSSL_ENGINE) + ENGINE *engine = NULL; +#endif + EVP_PKEY *evp_key = NULL; + FUNC_ENTRY; if (net->ctx == NULL) { +#if defined(OPENSSL_ENGINE) + net->using_engine = 0; +#endif + #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) net->ctx = SSL_CTX_new(TLS_client_method()); #else @@ -591,6 +615,30 @@ int SSLSocket_createContext(networkHandles* net, MQTTClient_SSLOptions* opts) SSLSocket_error("SSL_CTX_new", NULL, net->socket, rc, NULL, NULL); goto exit; } + +#if defined(OPENSSL_ENGINE) + if (opts->engine){ + Log(LOG_PROTOCOL, -1, "Loading engine: %s", opts->engine); + net->engine = ENGINE_by_id(opts->engine); + if (!net->engine){ + if (opts->struct_version >= 3) + SSLSocket_error("ENGINE_by_id", NULL, net->socket, rc, opts->ssl_error_cb, opts->ssl_error_context); + else + SSLSocket_error("ENGINE_by_id", NULL, net->socket, rc, NULL, NULL); + goto exit; + } + if (!ENGINE_init(net->engine)){ + if (opts->struct_version >= 3) + SSLSocket_error("ENGINE_init", NULL, net->socket, rc, opts->ssl_error_cb, opts->ssl_error_context); + else + SSLSocket_error("ENGINE_init", NULL, net->socket, rc, NULL, NULL); + goto exit; + } + ENGINE_set_default(net->engine, ENGINE_METHOD_ALL); + ENGINE_free(net->engine); + net->using_engine = 1; + } +#endif } /* @@ -610,27 +658,52 @@ int SSLSocket_createContext(networkHandles* net, MQTTClient_SSLOptions* opts) goto free_ctx; /*If we can't load the certificate (chain) file then loading the privatekey won't work either as it needs a matching cert already loaded */ } - if (opts->privateKey == NULL) - opts->privateKey = opts->keyStore; /* the privateKey can be included in the keyStore */ +#if defined(OPENSSL_ENGINE) + if (net->using_engine == 0) { +#endif + if (opts->privateKey == NULL) + opts->privateKey = opts->keyStore; /* the privateKey can be included in the keyStore */ - if (opts->privateKeyPassword != NULL) - { - SSL_CTX_set_default_passwd_cb(net->ctx, pem_passwd_cb); - SSL_CTX_set_default_passwd_cb_userdata(net->ctx, (void*)opts->privateKeyPassword); - } + if (opts->privateKeyPassword != NULL) + { + SSL_CTX_set_default_passwd_cb(net->ctx, pem_passwd_cb); + SSL_CTX_set_default_passwd_cb_userdata(net->ctx, (void*)opts->privateKeyPassword); + } - /* support for ASN.1 == DER format? DER can contain only one certificate? */ - rc = SSL_CTX_use_PrivateKey_file(net->ctx, opts->privateKey, SSL_FILETYPE_PEM); - if (opts->privateKey == opts->keyStore) - opts->privateKey = NULL; - if (rc != 1) + /* support for ASN.1 == DER format? DER can contain only one certificate? */ + rc = SSL_CTX_use_PrivateKey_file(net->ctx, opts->privateKey, SSL_FILETYPE_PEM); + if (opts->privateKey == opts->keyStore) + opts->privateKey = NULL; + if (rc != 1) + { + if (opts->struct_version >= 3) + SSLSocket_error("SSL_CTX_use_PrivateKey_file", NULL, net->socket, rc, opts->ssl_error_cb, opts->ssl_error_context); + else + SSLSocket_error("SSL_CTX_use_PrivateKey_file", NULL, net->socket, rc, NULL, NULL); + goto free_ctx; + } +#if defined(OPENSSL_ENGINE) + } + else { - if (opts->struct_version >= 3) - SSLSocket_error("SSL_CTX_use_PrivateKey_file", NULL, net->socket, rc, opts->ssl_error_cb, opts->ssl_error_context); - else - SSLSocket_error("SSL_CTX_use_PrivateKey_file", NULL, net->socket, rc, NULL, NULL); - goto free_ctx; + evp_key = ENGINE_load_private_key(net->engine, opts->privateKey, NULL, NULL); + if (!evp_key) { + if (opts->struct_version >= 3) + SSLSocket_error("ENGINE_load_private_key", NULL, net->socket, rc, opts->ssl_error_cb, opts->ssl_error_context); + else + SSLSocket_error("ENGINE_load_private_key", NULL, net->socket, rc, NULL, NULL); + goto free_ctx; + } + + if (SSL_CTX_use_PrivateKey(net->ctx, evp_key) != 1) { + if (opts->struct_version >= 3) + SSLSocket_error("SSL_CTX_use_PrivateKey", NULL, net->socket, rc, opts->ssl_error_cb, opts->ssl_error_context); + else + SSLSocket_error("SSL_CTX_use_PrivateKey", NULL, net->socket, rc, NULL, NULL); + goto free_ctx; + } } +#endif } if (opts->trustStore || opts->CApath) @@ -698,6 +771,12 @@ int SSLSocket_createContext(networkHandles* net, MQTTClient_SSLOptions* opts) goto exit; free_ctx: +#if defined(OPENSSL_ENGINE) + if (net->engine) { + ENGINE_finish(net->engine); + } +#endif + SSL_CTX_free(net->ctx); net->ctx = NULL; @@ -1042,7 +1121,7 @@ int SSLSocket_putdatas(SSL* ssl, SOCKET socket, char* buf0, size_t buf0len, Pack free(bufs.buffers[i]); bufs.buffers[i] = NULL; } - } + } } exit: FUNC_EXIT_RC(rc); diff --git a/src/samples/paho_c_pub.c b/src/samples/paho_c_pub.c index e891ef88c..269d74c6c 100644 --- a/src/samples/paho_c_pub.c +++ b/src/samples/paho_c_pub.c @@ -45,7 +45,7 @@ struct pubsub_opts opts = NULL, NULL, 1, 0, 0, /* message options */ MQTTVERSION_DEFAULT, NULL, "paho-c-pub", 0, 0, NULL, NULL, "localhost", "1883", NULL, 10, /* MQTT options */ NULL, NULL, 0, 0, /* will options */ - 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* TLS options */ + 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* TLS options */ 0, {NULL, NULL}, /* MQTT V5 options */ NULL, NULL, /* HTTP and HTTPS proxies */ }; @@ -326,6 +326,7 @@ void myconnect(MQTTAsync client) ssl_opts.privateKey = opts.key; ssl_opts.privateKeyPassword = opts.keypass; ssl_opts.enabledCipherSuites = opts.ciphers; + ssl_opts.engine = opts.engine; ssl_opts.ssl_error_cb = onSSLError; ssl_opts.ssl_error_context = client; ssl_opts.ssl_psk_cb = onPSKAuth; diff --git a/src/samples/paho_c_sub.c b/src/samples/paho_c_sub.c index 85875c991..2ea233e5a 100644 --- a/src/samples/paho_c_sub.c +++ b/src/samples/paho_c_sub.c @@ -66,7 +66,7 @@ struct pubsub_opts opts = NULL, NULL, 1, 0, 0, /* message options */ MQTTVERSION_DEFAULT, NULL, "paho-c-sub", 0, 0, NULL, NULL, "localhost", "1883", NULL, 10, /* MQTT options */ NULL, NULL, 0, 0, /* will options */ - 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* TLS options */ + 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* TLS options */ 0, {NULL, NULL}, /* MQTT V5 options */ NULL, NULL, /* HTTP and HTTPS proxies */ }; @@ -312,6 +312,7 @@ int main(int argc, char** argv) ssl_opts.privateKey = opts.key; ssl_opts.privateKeyPassword = opts.keypass; ssl_opts.enabledCipherSuites = opts.ciphers; + ssl_opts.engine = opts.engine; conn_opts.ssl = &ssl_opts; } diff --git a/src/samples/paho_cs_pub.c b/src/samples/paho_cs_pub.c index 1fce350a6..682a3a397 100644 --- a/src/samples/paho_cs_pub.c +++ b/src/samples/paho_cs_pub.c @@ -46,7 +46,7 @@ struct pubsub_opts opts = NULL, NULL, 1, 0, 0, /* message options */ MQTTVERSION_DEFAULT, NULL, "paho-cs-pub", 0, 0, NULL, NULL, "localhost", "1883", NULL, 10, /* MQTT options */ NULL, NULL, 0, 0, /* will options */ - 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* TLS options */ + 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* TLS options */ 0, {NULL, NULL}, /* MQTT V5 options */ NULL, NULL, /* HTTP and HTTPS proxies */ }; @@ -97,6 +97,7 @@ int myconnect(MQTTClient client) ssl_opts.privateKey = opts.key; ssl_opts.privateKeyPassword = opts.keypass; ssl_opts.enabledCipherSuites = opts.ciphers; + ssl_opts.engine = opts.engine; conn_opts.ssl = &ssl_opts; } diff --git a/src/samples/paho_cs_sub.c b/src/samples/paho_cs_sub.c index 39207376d..3814c3c59 100644 --- a/src/samples/paho_cs_sub.c +++ b/src/samples/paho_cs_sub.c @@ -43,7 +43,7 @@ struct pubsub_opts opts = NULL, NULL, 1, 0, 0, /* message options */ MQTTVERSION_DEFAULT, NULL, "paho-cs-sub", 0, 0, NULL, NULL, "localhost", "1883", NULL, 10, /* MQTT options */ NULL, NULL, 0, 0, /* will options */ - 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* TLS options */ + 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* TLS options */ 0, {NULL, NULL}, /* MQTT V5 options */ NULL, NULL, /* HTTP and HTTPS proxies */ }; @@ -94,6 +94,7 @@ int myconnect(MQTTClient client) ssl_opts.privateKey = opts.key; ssl_opts.privateKeyPassword = opts.keypass; ssl_opts.enabledCipherSuites = opts.ciphers; + ssl_opts.engine = opts.engine; conn_opts.ssl = &ssl_opts; } diff --git a/src/samples/pubsub_opts.c b/src/samples/pubsub_opts.c index 7acc4e90e..36cc285b6 100644 --- a/src/samples/pubsub_opts.c +++ b/src/samples/pubsub_opts.c @@ -55,7 +55,7 @@ void usage(struct pubsub_opts* opts, pubsub_opts_nameValue* name_values, const c printf(" [-R] [--no-delimiter]\n"); printf(" [--will-topic topic] [--will-payload message] [--will-qos qos] [--will-retain]\n"); printf(" [--cafile filename] [--capath dirname] [--cert filename] [--key filename]\n" - " [--keypass string] [--ciphers string] [--insecure]"); + " [--keypass string] [--ciphers string] [--insecure] [--engine]"); printf( "\n\n -t (--topic) : MQTT topic to %s to\n" @@ -117,6 +117,7 @@ void usage(struct pubsub_opts* opts, pubsub_opts_nameValue* name_values, const c " --insecure : don't check that the server certificate common name matches the hostname.\n" " --psk : pre-shared-key in hexadecimal (no leading 0x) \n" " --psk-identity : client identity string for TLS-PSK mode.\n" + " --engine : OpenSSL engine to use to load the private key.\n" ); printf( @@ -313,6 +314,13 @@ int getopts(int argc, char** argv, struct pubsub_opts* opts) else return 1; } + else if (strcmp(argv[count], "--engine") == 0) + { + if (++count < argc) + opts->engine = argv[count]; + else + return 1; + } else if (strcmp(argv[count], "--ciphers") == 0) { if (++count < argc) diff --git a/src/samples/pubsub_opts.h b/src/samples/pubsub_opts.h index 73bb09764..be49510d3 100644 --- a/src/samples/pubsub_opts.h +++ b/src/samples/pubsub_opts.h @@ -63,6 +63,7 @@ struct pubsub_opts char* ciphers; char* psk_identity; char* psk; + char* engine; /* MQTT V5 options */ int message_expiry; struct {