Commit 97ba2404 authored by Günter Obiltschnig's avatar Günter Obiltschnig

SSL/TLS: Add support for enforcing a TLS version through a new sslVersion field…

SSL/TLS: Add support for enforcing a TLS version through a new sslVersion field in the MQTTClient_SSLOptions structure. This affects which *_client_method() function is called in SSLSocket.c: 0 (default) -> SSLv23_client_method(), 1 -> TLSv1_client_method(), 2 -> TLSv1_1_client_method(), 3 -> TLSv1_2_client_method()
Signed-off-by: 's avatarGünter Obiltschnig <guenter.obiltschnig@appinf.com>
parent ea499805
......@@ -2222,7 +2222,7 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options)
}
if (options->struct_version != 0 && options->ssl) /* check validity of SSL options structure */
{
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version != 0)
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version < 0 || options->ssl->struct_version > 1)
{
rc = MQTTASYNC_BAD_STRUCTURE;
goto exit;
......@@ -2330,6 +2330,7 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options)
{
m->c->sslopts = malloc(sizeof(MQTTClient_SSLOptions));
memset(m->c->sslopts, '\0', sizeof(MQTTClient_SSLOptions));
m->c->sslopts->struct_version = options->ssl->struct_version;
if (options->ssl->trustStore)
m->c->sslopts->trustStore = MQTTStrdup(options->ssl->trustStore);
if (options->ssl->keyStore)
......@@ -2341,6 +2342,8 @@ int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options)
if (options->ssl->enabledCipherSuites)
m->c->sslopts->enabledCipherSuites = MQTTStrdup(options->ssl->enabledCipherSuites);
m->c->sslopts->enableServerCertAuth = options->ssl->enableServerCertAuth;
if (m->c->sslopts->struct_version >= 1)
m->c->sslopts->sslVersion = options->ssl->sslVersion;
}
#else
if (options->struct_version != 0 && options->ssl)
......
......@@ -630,6 +630,11 @@ typedef struct
#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } }
#define MQTT_SSL_VERSION_DEFAULT 0
#define MQTT_SSL_VERSION_TLS_1_0 1
#define MQTT_SSL_VERSION_TLS_1_1 2
#define MQTT_SSL_VERSION_TLS_1_2 3
/**
* MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the
* OpenSSL library. It covers the following scenarios:
......@@ -646,7 +651,7 @@ typedef struct
{
/** The eyecatcher for this structure. Must be MQTS */
char struct_id[4];
/** The version number of this structure. Must be 0 */
/** The version number of this structure. Must be 0, or 1 to enable TLS version selection. */
int struct_version;
/** The file in PEM format containing the public digital certificates trusted by the client. */
......@@ -677,9 +682,15 @@ typedef struct
/** True/False option to enable verification of the server certificate **/
int enableServerCertAuth;
/** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0),
* MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3).
* Only used if struct_version is >= 1.
*/
int sslVersion;
} MQTTAsync_SSLOptions;
#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 0, NULL, NULL, NULL, NULL, NULL, 1 }
#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 1, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT }
/**
* MQTTAsync_connectOptions defines several settings that control the way the
......
......@@ -1104,6 +1104,7 @@ static int MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectOptions* o
{
m->c->sslopts = malloc(sizeof(MQTTClient_SSLOptions));
memset(m->c->sslopts, '\0', sizeof(MQTTClient_SSLOptions));
m->c->sslopts->struct_version = options->ssl->struct_version;
if (options->ssl->trustStore)
m->c->sslopts->trustStore = MQTTStrdup(options->ssl->trustStore);
if (options->ssl->keyStore)
......@@ -1115,6 +1116,8 @@ static int MQTTClient_connectURI(MQTTClient handle, MQTTClient_connectOptions* o
if (options->ssl->enabledCipherSuites)
m->c->sslopts->enabledCipherSuites = MQTTStrdup(options->ssl->enabledCipherSuites);
m->c->sslopts->enableServerCertAuth = options->ssl->enableServerCertAuth;
if (m->c->sslopts->struct_version >= 1)
m->c->sslopts->sslVersion = options->ssl->sslVersion;
}
#endif
......@@ -1180,7 +1183,7 @@ int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options)
#if defined(OPENSSL)
if (options->struct_version != 0 && options->ssl) /* check validity of SSL options structure */
{
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version != 0)
if (strncmp(options->ssl->struct_id, "MQTS", 4) != 0 || options->ssl->struct_version < 0 || options->ssl->struct_version > 1)
{
rc = MQTTCLIENT_BAD_STRUCTURE;
goto exit;
......
......@@ -482,6 +482,11 @@ typedef struct
#define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} }
#define MQTT_SSL_VERSION_DEFAULT 0
#define MQTT_SSL_VERSION_TLS_1_0 1
#define MQTT_SSL_VERSION_TLS_1_1 2
#define MQTT_SSL_VERSION_TLS_1_2 3
/**
* MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the
* OpenSSL library. It covers the following scenarios:
......@@ -498,7 +503,7 @@ typedef struct
{
/** The eyecatcher for this structure. Must be MQTS */
char struct_id[4];
/** The version number of this structure. Must be 0 */
/** The version number of this structure. Must be 0, or 1 to enable TLS version selection. */
int struct_version;
/** The file in PEM format containing the public digital certificates trusted by the client. */
......@@ -529,9 +534,15 @@ typedef struct
/** True/False option to enable verification of the server certificate **/
int enableServerCertAuth;
/** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0),
* MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3).
* Only used if struct_version is >= 1.
*/
int sslVersion;
} MQTTClient_SSLOptions;
#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 0, NULL, NULL, NULL, NULL, NULL, 1 }
#define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 1, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT }
/**
* MQTTClient_connectOptions defines several settings that control the way the
......
......@@ -514,11 +514,42 @@ int SSLSocket_createContext(networkHandles* net, MQTTClient_SSLOptions* opts)
FUNC_ENTRY;
if (net->ctx == NULL)
if ((net->ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) /* SSLv23 for compatibility with SSLv2, SSLv3 and TLSv1 */
{
int sslVersion = MQTT_SSL_VERSION_DEFAULT;
if (opts->struct_version >= 1) sslVersion = opts->sslVersion;
/* SSL_OP_NO_TLSv1_1 is defined in ssl.h if the library version supports TLSv1.1.
* OPENSSL_NO_TLS1 is defined in opensslconf.h or on the compiler command line
* if TLS1.x was removed at OpenSSL library build time via Configure options.
*/
switch (sslVersion)
{
case MQTT_SSL_VERSION_DEFAULT:
net->ctx = SSL_CTX_new(SSLv23_client_method()); /* SSLv23 for compatibility with SSLv2, SSLv3 and TLSv1 */
break;
#if defined(SSL_OP_NO_TLSv1) && !defined(OPENSSL_NO_TLS1)
case MQTT_SSL_VERSION_TLS_1_0:
net->ctx = SSL_CTX_new(TLSv1_client_method());
break;
#endif
#if defined(SSL_OP_NO_TLSv1_1) && !defined(OPENSSL_NO_TLS1)
case MQTT_SSL_VERSION_TLS_1_1:
net->ctx = SSL_CTX_new(TLSv1_1_client_method());
break;
#endif
#if defined(SSL_OP_NO_TLSv1_2) && !defined(OPENSSL_NO_TLS1)
case MQTT_SSL_VERSION_TLS_1_2:
net->ctx = SSL_CTX_new(TLSv1_2_client_method());
break;
#endif
default:
break;
}
if (net->ctx == NULL)
{
SSLSocket_error("SSL_CTX_new", NULL, net->socket, rc);
goto exit;
}
}
if (opts->keyStore)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment