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 the ability to use a private key from an OpenSSL engine. #1531

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
55 changes: 40 additions & 15 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 $<TARGET_OBJECTS:common_ssl_obj> MQTTClient.c SSLSocket.c)
ADD_LIBRARY(paho-mqtt3as SHARED $<TARGET_OBJECTS:common_ssl_obj> 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)
Expand Down Expand Up @@ -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 $<TARGET_OBJECTS:common_ssl_obj_static> MQTTClient.c SSLSocket.c)
ADD_LIBRARY(paho-mqtt3as-static STATIC $<TARGET_OBJECTS:common_ssl_obj_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)
Expand Down
14 changes: 11 additions & 3 deletions src/Clients.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -29,6 +29,7 @@
#endif
#if defined(OPENSSL)
#include <openssl/ssl.h>
#include <openssl/engine.h>
#endif
#include "MQTTClient.h"
#include "LinkedList.h"
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions src/MQTTAsync.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion src/MQTTAsync.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 }
Expand Down
4 changes: 4 additions & 0 deletions src/MQTTClient.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion src/MQTTClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions src/MQTTProtocolClient.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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 */
Expand Down
Loading