Azure IoT common library

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Committer:
AzureIoTClient
Date:
Fri Aug 11 14:03:20 2017 -0700
Revision:
31:6a55d47aea41
Parent:
30:ce3813c5a692
Child:
38:ed9c888e5e12
1.1.21

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:fa2de1b79154 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:fa2de1b79154 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:fa2de1b79154 3
Azure.IoT Build 0:fa2de1b79154 4 #include <stdlib.h>
Azure.IoT Build 0:fa2de1b79154 5 #include "wolfssl/ssl.h"
Azure.IoT Build 0:fa2de1b79154 6 #include "wolfssl/error-ssl.h"
Azure.IoT Build 0:fa2de1b79154 7 #include <stdio.h>
Azure.IoT Build 0:fa2de1b79154 8 #include <stdbool.h>
Azure.IoT Build 0:fa2de1b79154 9 #include <string.h>
Azure.IoT Build 0:fa2de1b79154 10 #include "azure_c_shared_utility/tlsio.h"
Azure.IoT Build 0:fa2de1b79154 11 #include "azure_c_shared_utility/tlsio_wolfssl.h"
Azure.IoT Build 0:fa2de1b79154 12 #include "azure_c_shared_utility/socketio.h"
Azure.IoT Build 6:c55b013dfc2a 13 #include "azure_c_shared_utility/crt_abstractions.h"
AzureIoTClient 21:b92006c5b9ff 14 #include "azure_c_shared_utility/optimize_size.h"
Azure.IoT Build 6:c55b013dfc2a 15 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 15:956c6d205aa7 16 #include "azure_c_shared_utility/shared_util_options.h"
AzureIoTClient 15:956c6d205aa7 17
Azure.IoT Build 0:fa2de1b79154 18 typedef enum TLSIO_STATE_ENUM_TAG
Azure.IoT Build 0:fa2de1b79154 19 {
Azure.IoT Build 0:fa2de1b79154 20 TLSIO_STATE_NOT_OPEN,
Azure.IoT Build 0:fa2de1b79154 21 TLSIO_STATE_OPENING_UNDERLYING_IO,
Azure.IoT Build 0:fa2de1b79154 22 TLSIO_STATE_IN_HANDSHAKE,
Azure.IoT Build 0:fa2de1b79154 23 TLSIO_STATE_OPEN,
Azure.IoT Build 0:fa2de1b79154 24 TLSIO_STATE_CLOSING,
Azure.IoT Build 0:fa2de1b79154 25 TLSIO_STATE_ERROR
Azure.IoT Build 0:fa2de1b79154 26 } TLSIO_STATE_ENUM;
Azure.IoT Build 0:fa2de1b79154 27
Azure.IoT Build 0:fa2de1b79154 28 typedef struct TLS_IO_INSTANCE_TAG
Azure.IoT Build 0:fa2de1b79154 29 {
Azure.IoT Build 0:fa2de1b79154 30 XIO_HANDLE socket_io;
Azure.IoT Build 0:fa2de1b79154 31 ON_BYTES_RECEIVED on_bytes_received;
Azure.IoT Build 0:fa2de1b79154 32 ON_IO_OPEN_COMPLETE on_io_open_complete;
Azure.IoT Build 0:fa2de1b79154 33 ON_IO_CLOSE_COMPLETE on_io_close_complete;
Azure.IoT Build 0:fa2de1b79154 34 ON_IO_ERROR on_io_error;
Azure.IoT Build 0:fa2de1b79154 35 void* on_bytes_received_context;
Azure.IoT Build 0:fa2de1b79154 36 void* on_io_open_complete_context;
Azure.IoT Build 0:fa2de1b79154 37 void* on_io_close_complete_context;
Azure.IoT Build 0:fa2de1b79154 38 void* on_io_error_context;
Azure.IoT Build 0:fa2de1b79154 39 WOLFSSL* ssl;
Azure.IoT Build 0:fa2de1b79154 40 WOLFSSL_CTX* ssl_context;
Azure.IoT Build 0:fa2de1b79154 41 TLSIO_STATE_ENUM tlsio_state;
Azure.IoT Build 0:fa2de1b79154 42 unsigned char* socket_io_read_bytes;
Azure.IoT Build 0:fa2de1b79154 43 size_t socket_io_read_byte_count;
Azure.IoT Build 0:fa2de1b79154 44 ON_SEND_COMPLETE on_send_complete;
Azure.IoT Build 0:fa2de1b79154 45 void* on_send_complete_callback_context;
Azure.IoT Build 6:c55b013dfc2a 46 char* certificate;
AzureIoTClient 15:956c6d205aa7 47 char* x509certificate;
AzureIoTClient 15:956c6d205aa7 48 char* x509privatekey;
Azure.IoT Build 0:fa2de1b79154 49 } TLS_IO_INSTANCE;
Azure.IoT Build 0:fa2de1b79154 50
AzureIoTClient 10:1be0bc9a9deb 51 /*this function will clone an option given by name and value*/
AzureIoTClient 10:1be0bc9a9deb 52 static void* tlsio_wolfssl_CloneOption(const char* name, const void* value)
AzureIoTClient 10:1be0bc9a9deb 53 {
AzureIoTClient 10:1be0bc9a9deb 54 void* result;
AzureIoTClient 15:956c6d205aa7 55 if ((name == NULL) || (value == NULL))
AzureIoTClient 10:1be0bc9a9deb 56 {
AzureIoTClient 15:956c6d205aa7 57 LogError("invalid parameter detected: const char* name=%p, const void* value=%p", name, value);
AzureIoTClient 10:1be0bc9a9deb 58 result = NULL;
AzureIoTClient 10:1be0bc9a9deb 59 }
AzureIoTClient 10:1be0bc9a9deb 60 else
AzureIoTClient 10:1be0bc9a9deb 61 {
AzureIoTClient 10:1be0bc9a9deb 62 if (strcmp(name, "TrustedCerts") == 0)
AzureIoTClient 10:1be0bc9a9deb 63 {
AzureIoTClient 10:1be0bc9a9deb 64 if (mallocAndStrcpy_s((char**)&result, value) != 0)
AzureIoTClient 10:1be0bc9a9deb 65 {
AzureIoTClient 15:956c6d205aa7 66 LogError("unable to mallocAndStrcpy_s TrustedCerts value");
AzureIoTClient 15:956c6d205aa7 67 result = NULL;
AzureIoTClient 15:956c6d205aa7 68 }
AzureIoTClient 15:956c6d205aa7 69 else
AzureIoTClient 15:956c6d205aa7 70 {
AzureIoTClient 15:956c6d205aa7 71 /*return as is*/
AzureIoTClient 15:956c6d205aa7 72 }
AzureIoTClient 15:956c6d205aa7 73 }
AzureIoTClient 15:956c6d205aa7 74 else if (strcmp(name, SU_OPTION_X509_CERT) == 0)
AzureIoTClient 15:956c6d205aa7 75 {
AzureIoTClient 15:956c6d205aa7 76 if (mallocAndStrcpy_s((char**)&result, value) != 0)
AzureIoTClient 15:956c6d205aa7 77 {
AzureIoTClient 15:956c6d205aa7 78 LogError("unable to mallocAndStrcpy_s x509certificate value");
AzureIoTClient 15:956c6d205aa7 79 result = NULL;
AzureIoTClient 15:956c6d205aa7 80 }
AzureIoTClient 15:956c6d205aa7 81 else
AzureIoTClient 15:956c6d205aa7 82 {
AzureIoTClient 15:956c6d205aa7 83 /*return as is*/
AzureIoTClient 15:956c6d205aa7 84 }
AzureIoTClient 15:956c6d205aa7 85 }
AzureIoTClient 15:956c6d205aa7 86 else if (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0)
AzureIoTClient 15:956c6d205aa7 87 {
AzureIoTClient 15:956c6d205aa7 88 if (mallocAndStrcpy_s((char**)&result, value) != 0)
AzureIoTClient 15:956c6d205aa7 89 {
AzureIoTClient 15:956c6d205aa7 90 LogError("unable to mallocAndStrcpy_s x509privatekey value");
AzureIoTClient 10:1be0bc9a9deb 91 result = NULL;
AzureIoTClient 10:1be0bc9a9deb 92 }
AzureIoTClient 10:1be0bc9a9deb 93 else
AzureIoTClient 10:1be0bc9a9deb 94 {
AzureIoTClient 10:1be0bc9a9deb 95 /*return as is*/
AzureIoTClient 10:1be0bc9a9deb 96 }
AzureIoTClient 10:1be0bc9a9deb 97 }
AzureIoTClient 10:1be0bc9a9deb 98 else
AzureIoTClient 10:1be0bc9a9deb 99 {
AzureIoTClient 15:956c6d205aa7 100 LogError("not handled option : %s", name);
AzureIoTClient 10:1be0bc9a9deb 101 result = NULL;
AzureIoTClient 10:1be0bc9a9deb 102 }
AzureIoTClient 10:1be0bc9a9deb 103 }
AzureIoTClient 10:1be0bc9a9deb 104 return result;
AzureIoTClient 10:1be0bc9a9deb 105 }
AzureIoTClient 10:1be0bc9a9deb 106
AzureIoTClient 10:1be0bc9a9deb 107 /*this function destroys an option previously created*/
AzureIoTClient 10:1be0bc9a9deb 108 static void tlsio_wolfssl_DestroyOption(const char* name, const void* value)
AzureIoTClient 10:1be0bc9a9deb 109 {
AzureIoTClient 10:1be0bc9a9deb 110 /*since all options for this layer are actually string copies., disposing of one is just calling free*/
AzureIoTClient 15:956c6d205aa7 111 if ((name == NULL) || (value == NULL))
AzureIoTClient 10:1be0bc9a9deb 112 {
AzureIoTClient 15:956c6d205aa7 113 LogError("invalid parameter detected: const char* name=%p, const void* value=%p", name, value);
AzureIoTClient 15:956c6d205aa7 114 }
AzureIoTClient 15:956c6d205aa7 115 else
AzureIoTClient 15:956c6d205aa7 116 {
AzureIoTClient 15:956c6d205aa7 117 if ((strcmp(name, "TrustedCerts") == 0) ||
AzureIoTClient 15:956c6d205aa7 118 (strcmp(name, SU_OPTION_X509_CERT) == 0) ||
AzureIoTClient 15:956c6d205aa7 119 (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0))
AzureIoTClient 10:1be0bc9a9deb 120 {
AzureIoTClient 10:1be0bc9a9deb 121 free((void*)value);
AzureIoTClient 10:1be0bc9a9deb 122 }
AzureIoTClient 10:1be0bc9a9deb 123 else
AzureIoTClient 10:1be0bc9a9deb 124 {
AzureIoTClient 15:956c6d205aa7 125 LogError("not handled option : %s", name);
AzureIoTClient 10:1be0bc9a9deb 126 }
AzureIoTClient 10:1be0bc9a9deb 127 }
AzureIoTClient 10:1be0bc9a9deb 128 }
AzureIoTClient 10:1be0bc9a9deb 129
AzureIoTClient 10:1be0bc9a9deb 130 static OPTIONHANDLER_HANDLE tlsio_wolfssl_retrieveoptions(CONCRETE_IO_HANDLE tls_io)
AzureIoTClient 10:1be0bc9a9deb 131 {
AzureIoTClient 10:1be0bc9a9deb 132 OPTIONHANDLER_HANDLE result;
AzureIoTClient 19:2e0811512ceb 133 if (tls_io == NULL)
AzureIoTClient 10:1be0bc9a9deb 134 {
AzureIoTClient 19:2e0811512ceb 135 LogError("NULL tls_io parameter");
AzureIoTClient 19:2e0811512ceb 136 result = NULL;
AzureIoTClient 10:1be0bc9a9deb 137 }
AzureIoTClient 10:1be0bc9a9deb 138 else
AzureIoTClient 10:1be0bc9a9deb 139 {
AzureIoTClient 19:2e0811512ceb 140 result = OptionHandler_Create(tlsio_wolfssl_CloneOption, tlsio_wolfssl_DestroyOption, tlsio_wolfssl_setoption);
AzureIoTClient 19:2e0811512ceb 141 if (result == NULL)
AzureIoTClient 19:2e0811512ceb 142 {
AzureIoTClient 19:2e0811512ceb 143 LogError("unable to OptionHandler_Create");
AzureIoTClient 19:2e0811512ceb 144 /*return as is*/
AzureIoTClient 19:2e0811512ceb 145 }
AzureIoTClient 19:2e0811512ceb 146 else
AzureIoTClient 19:2e0811512ceb 147 {
AzureIoTClient 19:2e0811512ceb 148 /*this layer cares about the certificates and the x509 credentials*/
AzureIoTClient 19:2e0811512ceb 149 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
AzureIoTClient 19:2e0811512ceb 150 if (
AzureIoTClient 19:2e0811512ceb 151 (tls_io_instance->x509certificate != NULL) &&
AzureIoTClient 19:2e0811512ceb 152 (OptionHandler_AddOption(result, SU_OPTION_X509_CERT, tls_io_instance->x509certificate) != 0)
AzureIoTClient 19:2e0811512ceb 153 )
AzureIoTClient 19:2e0811512ceb 154 {
AzureIoTClient 19:2e0811512ceb 155 LogError("unable to save x509certificate option");
AzureIoTClient 19:2e0811512ceb 156 OptionHandler_Destroy(result);
AzureIoTClient 19:2e0811512ceb 157 result = NULL;
AzureIoTClient 19:2e0811512ceb 158 }
AzureIoTClient 19:2e0811512ceb 159 else if (
AzureIoTClient 19:2e0811512ceb 160 (tls_io_instance->x509privatekey != NULL) &&
AzureIoTClient 19:2e0811512ceb 161 (OptionHandler_AddOption(result, SU_OPTION_X509_PRIVATE_KEY, tls_io_instance->x509privatekey) != 0)
AzureIoTClient 19:2e0811512ceb 162 )
AzureIoTClient 19:2e0811512ceb 163 {
AzureIoTClient 19:2e0811512ceb 164 LogError("unable to save x509privatekey option");
AzureIoTClient 19:2e0811512ceb 165 OptionHandler_Destroy(result);
AzureIoTClient 19:2e0811512ceb 166 result = NULL;
AzureIoTClient 19:2e0811512ceb 167 }
AzureIoTClient 19:2e0811512ceb 168 else if (
AzureIoTClient 30:ce3813c5a692 169 (tls_io_instance->certificate != NULL) &&
AzureIoTClient 19:2e0811512ceb 170 (OptionHandler_AddOption(result, "TrustedCerts", tls_io_instance->certificate) != 0)
AzureIoTClient 19:2e0811512ceb 171 )
AzureIoTClient 19:2e0811512ceb 172 {
AzureIoTClient 19:2e0811512ceb 173 LogError("unable to save TrustedCerts option");
AzureIoTClient 19:2e0811512ceb 174 OptionHandler_Destroy(result);
AzureIoTClient 19:2e0811512ceb 175 result = NULL;
AzureIoTClient 19:2e0811512ceb 176 }
AzureIoTClient 19:2e0811512ceb 177 else
AzureIoTClient 19:2e0811512ceb 178 {
AzureIoTClient 19:2e0811512ceb 179 /*all is fine, all interesting options have been saved*/
AzureIoTClient 19:2e0811512ceb 180 /*return as is*/
AzureIoTClient 19:2e0811512ceb 181 }
AzureIoTClient 19:2e0811512ceb 182 }
AzureIoTClient 10:1be0bc9a9deb 183 }
AzureIoTClient 19:2e0811512ceb 184
AzureIoTClient 10:1be0bc9a9deb 185 return result;
AzureIoTClient 10:1be0bc9a9deb 186 }
AzureIoTClient 10:1be0bc9a9deb 187
Azure.IoT Build 0:fa2de1b79154 188 static const IO_INTERFACE_DESCRIPTION tlsio_wolfssl_interface_description =
Azure.IoT Build 0:fa2de1b79154 189 {
AzureIoTClient 10:1be0bc9a9deb 190 tlsio_wolfssl_retrieveoptions,
Azure.IoT Build 0:fa2de1b79154 191 tlsio_wolfssl_create,
Azure.IoT Build 0:fa2de1b79154 192 tlsio_wolfssl_destroy,
Azure.IoT Build 0:fa2de1b79154 193 tlsio_wolfssl_open,
Azure.IoT Build 0:fa2de1b79154 194 tlsio_wolfssl_close,
Azure.IoT Build 0:fa2de1b79154 195 tlsio_wolfssl_send,
Azure.IoT Build 0:fa2de1b79154 196 tlsio_wolfssl_dowork,
Azure.IoT Build 0:fa2de1b79154 197 tlsio_wolfssl_setoption
Azure.IoT Build 0:fa2de1b79154 198 };
Azure.IoT Build 0:fa2de1b79154 199
Azure.IoT Build 0:fa2de1b79154 200 static void indicate_error(TLS_IO_INSTANCE* tls_io_instance)
Azure.IoT Build 0:fa2de1b79154 201 {
Azure.IoT Build 0:fa2de1b79154 202 if (tls_io_instance->on_io_error != NULL)
Azure.IoT Build 0:fa2de1b79154 203 {
Azure.IoT Build 0:fa2de1b79154 204 tls_io_instance->on_io_error(tls_io_instance->on_io_error_context);
Azure.IoT Build 0:fa2de1b79154 205 }
Azure.IoT Build 0:fa2de1b79154 206 }
Azure.IoT Build 0:fa2de1b79154 207
Azure.IoT Build 0:fa2de1b79154 208 static void indicate_open_complete(TLS_IO_INSTANCE* tls_io_instance, IO_OPEN_RESULT open_result)
Azure.IoT Build 0:fa2de1b79154 209 {
Azure.IoT Build 0:fa2de1b79154 210 if (tls_io_instance->on_io_open_complete != NULL)
Azure.IoT Build 0:fa2de1b79154 211 {
Azure.IoT Build 0:fa2de1b79154 212 tls_io_instance->on_io_open_complete(tls_io_instance->on_io_open_complete_context, open_result);
Azure.IoT Build 0:fa2de1b79154 213 }
Azure.IoT Build 0:fa2de1b79154 214 }
Azure.IoT Build 0:fa2de1b79154 215
Azure.IoT Build 0:fa2de1b79154 216 static int decode_ssl_received_bytes(TLS_IO_INSTANCE* tls_io_instance)
Azure.IoT Build 0:fa2de1b79154 217 {
Azure.IoT Build 0:fa2de1b79154 218 int result = 0;
Azure.IoT Build 0:fa2de1b79154 219 unsigned char buffer[64];
Azure.IoT Build 0:fa2de1b79154 220
Azure.IoT Build 0:fa2de1b79154 221 int rcv_bytes = 1;
Azure.IoT Build 0:fa2de1b79154 222 while (rcv_bytes > 0)
Azure.IoT Build 0:fa2de1b79154 223 {
Azure.IoT Build 0:fa2de1b79154 224 rcv_bytes = wolfSSL_read(tls_io_instance->ssl, buffer, sizeof(buffer));
Azure.IoT Build 0:fa2de1b79154 225 if (rcv_bytes > 0)
Azure.IoT Build 0:fa2de1b79154 226 {
Azure.IoT Build 0:fa2de1b79154 227 if (tls_io_instance->on_bytes_received != NULL)
Azure.IoT Build 0:fa2de1b79154 228 {
Azure.IoT Build 0:fa2de1b79154 229 tls_io_instance->on_bytes_received(tls_io_instance->on_bytes_received_context, buffer, rcv_bytes);
Azure.IoT Build 0:fa2de1b79154 230 }
Azure.IoT Build 0:fa2de1b79154 231 }
Azure.IoT Build 0:fa2de1b79154 232 }
Azure.IoT Build 0:fa2de1b79154 233
Azure.IoT Build 0:fa2de1b79154 234 return result;
Azure.IoT Build 0:fa2de1b79154 235 }
Azure.IoT Build 0:fa2de1b79154 236
Azure.IoT Build 0:fa2de1b79154 237 static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_result)
Azure.IoT Build 0:fa2de1b79154 238 {
Azure.IoT Build 0:fa2de1b79154 239 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
Azure.IoT Build 0:fa2de1b79154 240
Azure.IoT Build 0:fa2de1b79154 241 if (open_result != IO_OPEN_OK)
Azure.IoT Build 0:fa2de1b79154 242 {
AzureIoTClient 19:2e0811512ceb 243 LogError("Underlying IO open failed");
Azure.IoT Build 0:fa2de1b79154 244 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
Azure.IoT Build 0:fa2de1b79154 245 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
Azure.IoT Build 0:fa2de1b79154 246 }
Azure.IoT Build 0:fa2de1b79154 247 else
Azure.IoT Build 0:fa2de1b79154 248 {
Azure.IoT Build 0:fa2de1b79154 249 int res;
Azure.IoT Build 0:fa2de1b79154 250 tls_io_instance->tlsio_state = TLSIO_STATE_IN_HANDSHAKE;
Azure.IoT Build 0:fa2de1b79154 251
Azure.IoT Build 0:fa2de1b79154 252 res = wolfSSL_connect(tls_io_instance->ssl);
Azure.IoT Build 0:fa2de1b79154 253 if (res != SSL_SUCCESS)
Azure.IoT Build 0:fa2de1b79154 254 {
AzureIoTClient 19:2e0811512ceb 255 LogError("WolfSSL connect failed");
Azure.IoT Build 0:fa2de1b79154 256 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
Azure.IoT Build 6:c55b013dfc2a 257 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
Azure.IoT Build 0:fa2de1b79154 258 }
Azure.IoT Build 0:fa2de1b79154 259 }
Azure.IoT Build 0:fa2de1b79154 260 }
Azure.IoT Build 0:fa2de1b79154 261
Azure.IoT Build 0:fa2de1b79154 262 static void on_underlying_io_bytes_received(void* context, const unsigned char* buffer, size_t size)
Azure.IoT Build 0:fa2de1b79154 263 {
Azure.IoT Build 0:fa2de1b79154 264 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
Azure.IoT Build 0:fa2de1b79154 265
Azure.IoT Build 0:fa2de1b79154 266 unsigned char* new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count + size);
Azure.IoT Build 0:fa2de1b79154 267 if (new_socket_io_read_bytes == NULL)
Azure.IoT Build 0:fa2de1b79154 268 {
AzureIoTClient 19:2e0811512ceb 269 LogError("Failed allocating memory for received bytes");
Azure.IoT Build 0:fa2de1b79154 270 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
Azure.IoT Build 0:fa2de1b79154 271 indicate_error(tls_io_instance);
Azure.IoT Build 0:fa2de1b79154 272 }
Azure.IoT Build 0:fa2de1b79154 273 else
Azure.IoT Build 0:fa2de1b79154 274 {
Azure.IoT Build 0:fa2de1b79154 275 tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes;
Azure.IoT Build 0:fa2de1b79154 276 (void)memcpy(tls_io_instance->socket_io_read_bytes + tls_io_instance->socket_io_read_byte_count, buffer, size);
Azure.IoT Build 0:fa2de1b79154 277 tls_io_instance->socket_io_read_byte_count += size;
Azure.IoT Build 0:fa2de1b79154 278 }
Azure.IoT Build 0:fa2de1b79154 279 }
Azure.IoT Build 0:fa2de1b79154 280
Azure.IoT Build 0:fa2de1b79154 281 static void on_underlying_io_error(void* context)
Azure.IoT Build 0:fa2de1b79154 282 {
Azure.IoT Build 0:fa2de1b79154 283 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
Azure.IoT Build 0:fa2de1b79154 284
Azure.IoT Build 0:fa2de1b79154 285 switch (tls_io_instance->tlsio_state)
Azure.IoT Build 0:fa2de1b79154 286 {
AzureIoTClient 15:956c6d205aa7 287 default:
AzureIoTClient 19:2e0811512ceb 288 LogError("Unknown TLS IO WolfSSL state: %d", (int)tls_io_instance->tlsio_state);
AzureIoTClient 19:2e0811512ceb 289 break;
AzureIoTClient 19:2e0811512ceb 290
AzureIoTClient 15:956c6d205aa7 291 case TLSIO_STATE_NOT_OPEN:
AzureIoTClient 15:956c6d205aa7 292 case TLSIO_STATE_ERROR:
AzureIoTClient 15:956c6d205aa7 293 break;
Azure.IoT Build 0:fa2de1b79154 294
AzureIoTClient 15:956c6d205aa7 295 case TLSIO_STATE_OPENING_UNDERLYING_IO:
AzureIoTClient 15:956c6d205aa7 296 case TLSIO_STATE_IN_HANDSHAKE:
AzureIoTClient 15:956c6d205aa7 297 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
AzureIoTClient 15:956c6d205aa7 298 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
AzureIoTClient 15:956c6d205aa7 299 break;
Azure.IoT Build 0:fa2de1b79154 300
AzureIoTClient 15:956c6d205aa7 301 case TLSIO_STATE_OPEN:
AzureIoTClient 15:956c6d205aa7 302 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
AzureIoTClient 15:956c6d205aa7 303 indicate_error(tls_io_instance);
AzureIoTClient 15:956c6d205aa7 304 break;
Azure.IoT Build 0:fa2de1b79154 305 }
Azure.IoT Build 0:fa2de1b79154 306 }
Azure.IoT Build 0:fa2de1b79154 307
Azure.IoT Build 0:fa2de1b79154 308 static void on_underlying_io_close_complete(void* context)
Azure.IoT Build 0:fa2de1b79154 309 {
Azure.IoT Build 0:fa2de1b79154 310 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
Azure.IoT Build 0:fa2de1b79154 311
AzureIoTClient 19:2e0811512ceb 312 if (tls_io_instance->tlsio_state != TLSIO_STATE_CLOSING)
AzureIoTClient 19:2e0811512ceb 313 {
AzureIoTClient 19:2e0811512ceb 314 LogError("on_underlying_io_close_complete called when not in CLOSING state");
AzureIoTClient 19:2e0811512ceb 315 }
AzureIoTClient 19:2e0811512ceb 316 else
Azure.IoT Build 0:fa2de1b79154 317 {
Azure.IoT Build 0:fa2de1b79154 318 if (tls_io_instance->on_io_close_complete != NULL)
Azure.IoT Build 0:fa2de1b79154 319 {
Azure.IoT Build 0:fa2de1b79154 320 tls_io_instance->on_io_close_complete(tls_io_instance->on_io_close_complete_context);
Azure.IoT Build 0:fa2de1b79154 321 }
Azure.IoT Build 6:c55b013dfc2a 322 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
Azure.IoT Build 0:fa2de1b79154 323 }
Azure.IoT Build 0:fa2de1b79154 324 }
Azure.IoT Build 0:fa2de1b79154 325
Azure.IoT Build 0:fa2de1b79154 326 static int on_io_recv(WOLFSSL *ssl, char *buf, int sz, void *context)
Azure.IoT Build 0:fa2de1b79154 327 {
Azure.IoT Build 0:fa2de1b79154 328 int result;
Azure.IoT Build 0:fa2de1b79154 329 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
Azure.IoT Build 0:fa2de1b79154 330 unsigned char* new_socket_io_read_bytes;
Azure.IoT Build 0:fa2de1b79154 331
AzureIoTClient 15:956c6d205aa7 332 (void)ssl;
Azure.IoT Build 0:fa2de1b79154 333 while (tls_io_instance->socket_io_read_byte_count == 0)
Azure.IoT Build 0:fa2de1b79154 334 {
Azure.IoT Build 0:fa2de1b79154 335 xio_dowork(tls_io_instance->socket_io);
Azure.IoT Build 6:c55b013dfc2a 336 if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE)
Azure.IoT Build 0:fa2de1b79154 337 {
Azure.IoT Build 0:fa2de1b79154 338 break;
Azure.IoT Build 0:fa2de1b79154 339 }
Azure.IoT Build 0:fa2de1b79154 340 }
Azure.IoT Build 0:fa2de1b79154 341
Azure.IoT Build 0:fa2de1b79154 342 result = tls_io_instance->socket_io_read_byte_count;
Azure.IoT Build 0:fa2de1b79154 343 if (result > sz)
Azure.IoT Build 0:fa2de1b79154 344 {
Azure.IoT Build 0:fa2de1b79154 345 result = sz;
Azure.IoT Build 0:fa2de1b79154 346 }
Azure.IoT Build 0:fa2de1b79154 347
Azure.IoT Build 0:fa2de1b79154 348 if (result > 0)
Azure.IoT Build 0:fa2de1b79154 349 {
Azure.IoT Build 0:fa2de1b79154 350 (void)memcpy(buf, tls_io_instance->socket_io_read_bytes, result);
Azure.IoT Build 0:fa2de1b79154 351 (void)memmove(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_bytes + result, tls_io_instance->socket_io_read_byte_count - result);
Azure.IoT Build 0:fa2de1b79154 352 tls_io_instance->socket_io_read_byte_count -= result;
Azure.IoT Build 0:fa2de1b79154 353 if (tls_io_instance->socket_io_read_byte_count > 0)
Azure.IoT Build 0:fa2de1b79154 354 {
Azure.IoT Build 0:fa2de1b79154 355 new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count);
Azure.IoT Build 0:fa2de1b79154 356 if (new_socket_io_read_bytes != NULL)
Azure.IoT Build 0:fa2de1b79154 357 {
Azure.IoT Build 0:fa2de1b79154 358 tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes;
Azure.IoT Build 0:fa2de1b79154 359 }
Azure.IoT Build 0:fa2de1b79154 360 }
Azure.IoT Build 0:fa2de1b79154 361 else
Azure.IoT Build 0:fa2de1b79154 362 {
Azure.IoT Build 0:fa2de1b79154 363 free(tls_io_instance->socket_io_read_bytes);
Azure.IoT Build 0:fa2de1b79154 364 tls_io_instance->socket_io_read_bytes = NULL;
Azure.IoT Build 0:fa2de1b79154 365 }
Azure.IoT Build 0:fa2de1b79154 366 }
Azure.IoT Build 0:fa2de1b79154 367
Azure.IoT Build 0:fa2de1b79154 368 if ((result == 0) && (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN))
Azure.IoT Build 0:fa2de1b79154 369 {
Azure.IoT Build 0:fa2de1b79154 370 result = WOLFSSL_CBIO_ERR_WANT_READ;
Azure.IoT Build 0:fa2de1b79154 371 }
Azure.IoT Build 6:c55b013dfc2a 372 else if ((result == 0) && tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING)
Azure.IoT Build 6:c55b013dfc2a 373 {
Azure.IoT Build 6:c55b013dfc2a 374 result = WOLFSSL_CBIO_ERR_CONN_CLOSE;
Azure.IoT Build 6:c55b013dfc2a 375 }
Azure.IoT Build 0:fa2de1b79154 376
Azure.IoT Build 0:fa2de1b79154 377 return result;
Azure.IoT Build 0:fa2de1b79154 378 }
Azure.IoT Build 0:fa2de1b79154 379
Azure.IoT Build 0:fa2de1b79154 380 static int on_io_send(WOLFSSL *ssl, char *buf, int sz, void *context)
Azure.IoT Build 0:fa2de1b79154 381 {
Azure.IoT Build 0:fa2de1b79154 382 int result;
Azure.IoT Build 0:fa2de1b79154 383 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
Azure.IoT Build 0:fa2de1b79154 384
AzureIoTClient 15:956c6d205aa7 385 (void)ssl;
Azure.IoT Build 0:fa2de1b79154 386 if (xio_send(tls_io_instance->socket_io, buf, sz, tls_io_instance->on_send_complete, tls_io_instance->on_send_complete_callback_context) != 0)
Azure.IoT Build 0:fa2de1b79154 387 {
AzureIoTClient 19:2e0811512ceb 388 LogError("Failed sending bytes through underlying IO");
Azure.IoT Build 0:fa2de1b79154 389 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
Azure.IoT Build 0:fa2de1b79154 390 indicate_error(tls_io_instance);
Azure.IoT Build 0:fa2de1b79154 391 result = 0;
Azure.IoT Build 0:fa2de1b79154 392 }
Azure.IoT Build 0:fa2de1b79154 393 else
Azure.IoT Build 0:fa2de1b79154 394 {
Azure.IoT Build 0:fa2de1b79154 395 result = sz;
Azure.IoT Build 0:fa2de1b79154 396 }
Azure.IoT Build 0:fa2de1b79154 397
Azure.IoT Build 0:fa2de1b79154 398 return result;
Azure.IoT Build 0:fa2de1b79154 399 }
Azure.IoT Build 0:fa2de1b79154 400
Azure.IoT Build 0:fa2de1b79154 401 static int on_handshake_done(WOLFSSL* ssl, void* context)
Azure.IoT Build 0:fa2de1b79154 402 {
Azure.IoT Build 0:fa2de1b79154 403 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context;
AzureIoTClient 15:956c6d205aa7 404 (void)ssl;
AzureIoTClient 19:2e0811512ceb 405 if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE)
AzureIoTClient 19:2e0811512ceb 406 {
AzureIoTClient 19:2e0811512ceb 407 LogInfo("on_handshake_done called when not in IN_HANDSHAKE state");
AzureIoTClient 19:2e0811512ceb 408 }
AzureIoTClient 19:2e0811512ceb 409 else
Azure.IoT Build 0:fa2de1b79154 410 {
Azure.IoT Build 0:fa2de1b79154 411 tls_io_instance->tlsio_state = TLSIO_STATE_OPEN;
Azure.IoT Build 0:fa2de1b79154 412 indicate_open_complete(tls_io_instance, IO_OPEN_OK);
Azure.IoT Build 0:fa2de1b79154 413 }
Azure.IoT Build 0:fa2de1b79154 414
Azure.IoT Build 0:fa2de1b79154 415 return 0;
Azure.IoT Build 0:fa2de1b79154 416 }
Azure.IoT Build 0:fa2de1b79154 417
Azure.IoT Build 6:c55b013dfc2a 418 static int add_certificate_to_store(TLS_IO_INSTANCE* tls_io_instance)
Azure.IoT Build 6:c55b013dfc2a 419 {
Azure.IoT Build 6:c55b013dfc2a 420 int result;
Azure.IoT Build 6:c55b013dfc2a 421 if (tls_io_instance->certificate != NULL)
Azure.IoT Build 6:c55b013dfc2a 422 {
AzureIoTClient 31:6a55d47aea41 423 int res = wolfSSL_CTX_load_verify_buffer(tls_io_instance->ssl_context, (const unsigned char*)tls_io_instance->certificate, strlen(tls_io_instance->certificate), SSL_FILETYPE_PEM);
Azure.IoT Build 6:c55b013dfc2a 424 if (res != SSL_SUCCESS)
Azure.IoT Build 6:c55b013dfc2a 425 {
AzureIoTClient 19:2e0811512ceb 426 LogError("wolfSSL_CTX_load_verify_buffer failed");
AzureIoTClient 21:b92006c5b9ff 427 result = __FAILURE__;
Azure.IoT Build 6:c55b013dfc2a 428 }
Azure.IoT Build 6:c55b013dfc2a 429 else
Azure.IoT Build 6:c55b013dfc2a 430 {
Azure.IoT Build 6:c55b013dfc2a 431 result = 0;
Azure.IoT Build 6:c55b013dfc2a 432 }
Azure.IoT Build 6:c55b013dfc2a 433 }
Azure.IoT Build 6:c55b013dfc2a 434 else
Azure.IoT Build 6:c55b013dfc2a 435 {
Azure.IoT Build 6:c55b013dfc2a 436 result = 0;
Azure.IoT Build 6:c55b013dfc2a 437 }
Azure.IoT Build 6:c55b013dfc2a 438 return result;
Azure.IoT Build 6:c55b013dfc2a 439 }
Azure.IoT Build 6:c55b013dfc2a 440
AzureIoTClient 15:956c6d205aa7 441 static int x509_wolfssl_add_credentials(WOLFSSL* ssl, char* x509certificate, char* x509privatekey) {
AzureIoTClient 15:956c6d205aa7 442
AzureIoTClient 15:956c6d205aa7 443 int result;
AzureIoTClient 15:956c6d205aa7 444
AzureIoTClient 31:6a55d47aea41 445 if (wolfSSL_use_certificate_chain_buffer(ssl, (unsigned char*)x509certificate, strlen(x509certificate)) != SSL_SUCCESS)
AzureIoTClient 15:956c6d205aa7 446 {
AzureIoTClient 15:956c6d205aa7 447 LogError("unable to load x509 client certificate");
AzureIoTClient 21:b92006c5b9ff 448 result = __FAILURE__;
AzureIoTClient 15:956c6d205aa7 449 }
AzureIoTClient 31:6a55d47aea41 450 else if (wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)x509privatekey, strlen(x509privatekey), SSL_FILETYPE_PEM) != SSL_SUCCESS)
AzureIoTClient 15:956c6d205aa7 451 {
AzureIoTClient 15:956c6d205aa7 452 LogError("unable to load x509 client private key");
AzureIoTClient 21:b92006c5b9ff 453 result = __FAILURE__;
AzureIoTClient 15:956c6d205aa7 454 }
AzureIoTClient 15:956c6d205aa7 455 #ifdef HAVE_SECURE_RENEGOTIATION
AzureIoTClient 19:2e0811512ceb 456 else if (wolfSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS)
AzureIoTClient 19:2e0811512ceb 457 {
AzureIoTClient 15:956c6d205aa7 458 LogError("unable to enable secure renegotiation");
AzureIoTClient 21:b92006c5b9ff 459 result = __FAILURE__;
AzureIoTClient 15:956c6d205aa7 460 }
AzureIoTClient 15:956c6d205aa7 461 #endif
AzureIoTClient 15:956c6d205aa7 462 else
AzureIoTClient 15:956c6d205aa7 463 {
AzureIoTClient 15:956c6d205aa7 464 result = 0;
AzureIoTClient 15:956c6d205aa7 465 }
AzureIoTClient 15:956c6d205aa7 466 return result;
AzureIoTClient 15:956c6d205aa7 467 }
AzureIoTClient 15:956c6d205aa7 468
AzureIoTClient 15:956c6d205aa7 469 static void destroy_wolfssl_instance(TLS_IO_INSTANCE* tls_io_instance)
AzureIoTClient 15:956c6d205aa7 470 {
AzureIoTClient 15:956c6d205aa7 471 wolfSSL_free(tls_io_instance->ssl);
AzureIoTClient 15:956c6d205aa7 472 }
AzureIoTClient 15:956c6d205aa7 473
Azure.IoT Build 6:c55b013dfc2a 474 static int create_wolfssl_instance(TLS_IO_INSTANCE* tls_io_instance)
Azure.IoT Build 6:c55b013dfc2a 475 {
Azure.IoT Build 6:c55b013dfc2a 476 int result;
Azure.IoT Build 6:c55b013dfc2a 477
Azure.IoT Build 6:c55b013dfc2a 478 if (add_certificate_to_store(tls_io_instance) != 0)
Azure.IoT Build 6:c55b013dfc2a 479 {
AzureIoTClient 19:2e0811512ceb 480 LogError("Failed to add certificates to store");
AzureIoTClient 21:b92006c5b9ff 481 result = __FAILURE__;
Azure.IoT Build 6:c55b013dfc2a 482 }
Azure.IoT Build 6:c55b013dfc2a 483 else
Azure.IoT Build 6:c55b013dfc2a 484 {
Azure.IoT Build 6:c55b013dfc2a 485 tls_io_instance->ssl = wolfSSL_new(tls_io_instance->ssl_context);
Azure.IoT Build 6:c55b013dfc2a 486 if (tls_io_instance->ssl == NULL)
Azure.IoT Build 6:c55b013dfc2a 487 {
AzureIoTClient 19:2e0811512ceb 488 LogError("Failed to add certificates to store");
AzureIoTClient 21:b92006c5b9ff 489 result = __FAILURE__;
Azure.IoT Build 6:c55b013dfc2a 490 }
AzureIoTClient 15:956c6d205aa7 491 /*x509 authentication can only be build before underlying connection is realized*/
AzureIoTClient 15:956c6d205aa7 492 else if ((tls_io_instance->x509certificate != NULL) &&
AzureIoTClient 15:956c6d205aa7 493 (tls_io_instance->x509privatekey != NULL) &&
AzureIoTClient 15:956c6d205aa7 494 (x509_wolfssl_add_credentials(tls_io_instance->ssl, tls_io_instance->x509certificate, tls_io_instance->x509privatekey) != 0))
AzureIoTClient 15:956c6d205aa7 495 {
AzureIoTClient 15:956c6d205aa7 496 destroy_wolfssl_instance(tls_io_instance);
AzureIoTClient 15:956c6d205aa7 497 LogError("unable to use x509 authentication");
AzureIoTClient 21:b92006c5b9ff 498 result = __FAILURE__;
AzureIoTClient 15:956c6d205aa7 499 }
Azure.IoT Build 6:c55b013dfc2a 500 else
Azure.IoT Build 6:c55b013dfc2a 501 {
Azure.IoT Build 6:c55b013dfc2a 502 tls_io_instance->socket_io_read_bytes = NULL;
Azure.IoT Build 6:c55b013dfc2a 503 tls_io_instance->socket_io_read_byte_count = 0;
Azure.IoT Build 6:c55b013dfc2a 504 tls_io_instance->on_send_complete = NULL;
Azure.IoT Build 6:c55b013dfc2a 505 tls_io_instance->on_send_complete_callback_context = NULL;
Azure.IoT Build 6:c55b013dfc2a 506
Azure.IoT Build 6:c55b013dfc2a 507 wolfSSL_set_using_nonblock(tls_io_instance->ssl, 1);
Azure.IoT Build 6:c55b013dfc2a 508 wolfSSL_SetIOSend(tls_io_instance->ssl_context, on_io_send);
Azure.IoT Build 6:c55b013dfc2a 509 wolfSSL_SetIORecv(tls_io_instance->ssl_context, on_io_recv);
Azure.IoT Build 6:c55b013dfc2a 510 wolfSSL_SetHsDoneCb(tls_io_instance->ssl, on_handshake_done, tls_io_instance);
Azure.IoT Build 6:c55b013dfc2a 511 wolfSSL_SetIOWriteCtx(tls_io_instance->ssl, tls_io_instance);
Azure.IoT Build 6:c55b013dfc2a 512 wolfSSL_SetIOReadCtx(tls_io_instance->ssl, tls_io_instance);
Azure.IoT Build 6:c55b013dfc2a 513
Azure.IoT Build 6:c55b013dfc2a 514 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
Azure.IoT Build 6:c55b013dfc2a 515 result = 0;
Azure.IoT Build 6:c55b013dfc2a 516 }
Azure.IoT Build 6:c55b013dfc2a 517 }
AzureIoTClient 19:2e0811512ceb 518
Azure.IoT Build 6:c55b013dfc2a 519 return result;
Azure.IoT Build 6:c55b013dfc2a 520 }
Azure.IoT Build 6:c55b013dfc2a 521
Azure.IoT Build 0:fa2de1b79154 522 int tlsio_wolfssl_init(void)
Azure.IoT Build 0:fa2de1b79154 523 {
Azure.IoT Build 0:fa2de1b79154 524 (void)wolfSSL_library_init();
Azure.IoT Build 0:fa2de1b79154 525 wolfSSL_load_error_strings();
Azure.IoT Build 0:fa2de1b79154 526
Azure.IoT Build 0:fa2de1b79154 527 return 0;
Azure.IoT Build 0:fa2de1b79154 528 }
Azure.IoT Build 0:fa2de1b79154 529
Azure.IoT Build 0:fa2de1b79154 530 void tlsio_wolfssl_deinit(void)
Azure.IoT Build 0:fa2de1b79154 531 {
Azure.IoT Build 0:fa2de1b79154 532 }
AzureIoTClient 31:6a55d47aea41 533
Azure.IoT Build 6:c55b013dfc2a 534 CONCRETE_IO_HANDLE tlsio_wolfssl_create(void* io_create_parameters)
Azure.IoT Build 0:fa2de1b79154 535 {
Azure.IoT Build 0:fa2de1b79154 536 TLS_IO_INSTANCE* result;
Azure.IoT Build 0:fa2de1b79154 537
AzureIoTClient 19:2e0811512ceb 538 if (io_create_parameters == NULL)
Azure.IoT Build 0:fa2de1b79154 539 {
AzureIoTClient 19:2e0811512ceb 540 LogError("NULL io_create_parameters");
Azure.IoT Build 0:fa2de1b79154 541 result = NULL;
Azure.IoT Build 0:fa2de1b79154 542 }
Azure.IoT Build 0:fa2de1b79154 543 else
Azure.IoT Build 0:fa2de1b79154 544 {
AzureIoTClient 19:2e0811512ceb 545 TLSIO_CONFIG* tls_io_config = io_create_parameters;
AzureIoTClient 19:2e0811512ceb 546
Azure.IoT Build 6:c55b013dfc2a 547 result = (TLS_IO_INSTANCE*)malloc(sizeof(TLS_IO_INSTANCE));
AzureIoTClient 22:10640b226104 548 if (result == NULL)
AzureIoTClient 22:10640b226104 549 {
AzureIoTClient 22:10640b226104 550 LogError("Failed allocating memory for the TLS IO instance.");
AzureIoTClient 22:10640b226104 551 }
AzureIoTClient 22:10640b226104 552 else
Azure.IoT Build 0:fa2de1b79154 553 {
AzureIoTClient 22:10640b226104 554 (void)memset(result, 0, sizeof(TLS_IO_INSTANCE));
AzureIoTClient 22:10640b226104 555
AzureIoTClient 22:10640b226104 556 result->socket_io_read_bytes = 0;
AzureIoTClient 22:10640b226104 557 result->socket_io_read_byte_count = 0;
AzureIoTClient 22:10640b226104 558 result->socket_io = NULL;
AzureIoTClient 22:10640b226104 559
AzureIoTClient 22:10640b226104 560 result->ssl = NULL;
AzureIoTClient 22:10640b226104 561 result->certificate = NULL;
AzureIoTClient 22:10640b226104 562 result->x509certificate = NULL;
AzureIoTClient 22:10640b226104 563 result->x509privatekey = NULL;
AzureIoTClient 22:10640b226104 564
AzureIoTClient 22:10640b226104 565 result->on_bytes_received = NULL;
AzureIoTClient 22:10640b226104 566 result->on_bytes_received_context = NULL;
AzureIoTClient 22:10640b226104 567
AzureIoTClient 22:10640b226104 568 result->on_io_open_complete = NULL;
AzureIoTClient 22:10640b226104 569 result->on_io_open_complete_context = NULL;
AzureIoTClient 22:10640b226104 570
AzureIoTClient 22:10640b226104 571 result->on_io_close_complete = NULL;
AzureIoTClient 22:10640b226104 572 result->on_io_close_complete_context = NULL;
AzureIoTClient 22:10640b226104 573
AzureIoTClient 22:10640b226104 574 result->on_io_error = NULL;
AzureIoTClient 22:10640b226104 575 result->on_io_error_context = NULL;
AzureIoTClient 22:10640b226104 576
AzureIoTClient 22:10640b226104 577 result->tlsio_state = TLSIO_STATE_NOT_OPEN;
AzureIoTClient 22:10640b226104 578
AzureIoTClient 22:10640b226104 579 result->ssl_context = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
AzureIoTClient 22:10640b226104 580 if (result->ssl_context == NULL)
Azure.IoT Build 0:fa2de1b79154 581 {
AzureIoTClient 22:10640b226104 582 LogError("Cannot create the wolfSSL context");
Azure.IoT Build 0:fa2de1b79154 583 free(result);
Azure.IoT Build 0:fa2de1b79154 584 result = NULL;
Azure.IoT Build 0:fa2de1b79154 585 }
Azure.IoT Build 0:fa2de1b79154 586 else
Azure.IoT Build 0:fa2de1b79154 587 {
AzureIoTClient 22:10640b226104 588 const IO_INTERFACE_DESCRIPTION* underlying_io_interface;
AzureIoTClient 22:10640b226104 589 void* io_interface_parameters;
AzureIoTClient 19:2e0811512ceb 590
AzureIoTClient 22:10640b226104 591 if (tls_io_config->underlying_io_interface != NULL)
AzureIoTClient 22:10640b226104 592 {
AzureIoTClient 22:10640b226104 593 underlying_io_interface = tls_io_config->underlying_io_interface;
AzureIoTClient 22:10640b226104 594 io_interface_parameters = tls_io_config->underlying_io_parameters;
AzureIoTClient 22:10640b226104 595 }
AzureIoTClient 22:10640b226104 596 else
AzureIoTClient 22:10640b226104 597 {
AzureIoTClient 22:10640b226104 598 SOCKETIO_CONFIG socketio_config;
AzureIoTClient 19:2e0811512ceb 599
AzureIoTClient 22:10640b226104 600 socketio_config.hostname = tls_io_config->hostname;
AzureIoTClient 22:10640b226104 601 socketio_config.port = tls_io_config->port;
AzureIoTClient 22:10640b226104 602 socketio_config.accepted_socket = NULL;
AzureIoTClient 19:2e0811512ceb 603
AzureIoTClient 22:10640b226104 604 underlying_io_interface = socketio_get_interface_description();
AzureIoTClient 22:10640b226104 605 io_interface_parameters = &socketio_config;
AzureIoTClient 22:10640b226104 606 }
AzureIoTClient 19:2e0811512ceb 607
AzureIoTClient 22:10640b226104 608 if (underlying_io_interface == NULL)
Azure.IoT Build 0:fa2de1b79154 609 {
AzureIoTClient 22:10640b226104 610 LogError("Failed getting socket IO interface description.");
AzureIoTClient 22:10640b226104 611 wolfSSL_CTX_free(result->ssl_context);
Azure.IoT Build 0:fa2de1b79154 612 free(result);
Azure.IoT Build 0:fa2de1b79154 613 result = NULL;
Azure.IoT Build 0:fa2de1b79154 614 }
Azure.IoT Build 0:fa2de1b79154 615 else
Azure.IoT Build 0:fa2de1b79154 616 {
AzureIoTClient 22:10640b226104 617 result->socket_io = xio_create(underlying_io_interface, io_interface_parameters);
AzureIoTClient 22:10640b226104 618 if (result->socket_io == NULL)
Azure.IoT Build 0:fa2de1b79154 619 {
AzureIoTClient 22:10640b226104 620 LogError("Failure connecting to underlying socket_io");
Azure.IoT Build 0:fa2de1b79154 621 wolfSSL_CTX_free(result->ssl_context);
Azure.IoT Build 0:fa2de1b79154 622 free(result);
Azure.IoT Build 0:fa2de1b79154 623 result = NULL;
Azure.IoT Build 0:fa2de1b79154 624 }
Azure.IoT Build 0:fa2de1b79154 625 }
Azure.IoT Build 0:fa2de1b79154 626 }
Azure.IoT Build 0:fa2de1b79154 627 }
Azure.IoT Build 0:fa2de1b79154 628 }
Azure.IoT Build 0:fa2de1b79154 629
Azure.IoT Build 0:fa2de1b79154 630 return result;
Azure.IoT Build 0:fa2de1b79154 631 }
Azure.IoT Build 0:fa2de1b79154 632
Azure.IoT Build 0:fa2de1b79154 633 void tlsio_wolfssl_destroy(CONCRETE_IO_HANDLE tls_io)
Azure.IoT Build 0:fa2de1b79154 634 {
Azure.IoT Build 0:fa2de1b79154 635 if (tls_io != NULL)
Azure.IoT Build 0:fa2de1b79154 636 {
Azure.IoT Build 0:fa2de1b79154 637 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
Azure.IoT Build 0:fa2de1b79154 638 if (tls_io_instance->socket_io_read_bytes != NULL)
Azure.IoT Build 0:fa2de1b79154 639 {
Azure.IoT Build 0:fa2de1b79154 640 free(tls_io_instance->socket_io_read_bytes);
Azure.IoT Build 0:fa2de1b79154 641 }
Azure.IoT Build 0:fa2de1b79154 642
Azure.IoT Build 6:c55b013dfc2a 643 if (tls_io_instance->certificate != NULL)
Azure.IoT Build 6:c55b013dfc2a 644 {
Azure.IoT Build 6:c55b013dfc2a 645 free(tls_io_instance->certificate);
Azure.IoT Build 6:c55b013dfc2a 646 }
AzureIoTClient 15:956c6d205aa7 647 if (tls_io_instance->x509certificate != NULL)
AzureIoTClient 15:956c6d205aa7 648 {
AzureIoTClient 15:956c6d205aa7 649 free(tls_io_instance->x509certificate);
AzureIoTClient 15:956c6d205aa7 650 }
AzureIoTClient 15:956c6d205aa7 651 if (tls_io_instance->x509privatekey != NULL)
AzureIoTClient 15:956c6d205aa7 652 {
AzureIoTClient 15:956c6d205aa7 653 free(tls_io_instance->x509privatekey);
AzureIoTClient 15:956c6d205aa7 654 }
AzureIoTClient 19:2e0811512ceb 655
Azure.IoT Build 6:c55b013dfc2a 656 wolfSSL_CTX_free(tls_io_instance->ssl_context);
Azure.IoT Build 0:fa2de1b79154 657 xio_destroy(tls_io_instance->socket_io);
Azure.IoT Build 0:fa2de1b79154 658 free(tls_io);
Azure.IoT Build 0:fa2de1b79154 659 }
Azure.IoT Build 0:fa2de1b79154 660 }
Azure.IoT Build 0:fa2de1b79154 661
Azure.IoT Build 0:fa2de1b79154 662 int tlsio_wolfssl_open(CONCRETE_IO_HANDLE tls_io, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context)
Azure.IoT Build 0:fa2de1b79154 663 {
Azure.IoT Build 0:fa2de1b79154 664 int result;
Azure.IoT Build 0:fa2de1b79154 665
Azure.IoT Build 0:fa2de1b79154 666 if (tls_io == NULL)
Azure.IoT Build 0:fa2de1b79154 667 {
AzureIoTClient 19:2e0811512ceb 668 LogError("NULL tls_io instance");
AzureIoTClient 21:b92006c5b9ff 669 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 670 }
Azure.IoT Build 0:fa2de1b79154 671 else
Azure.IoT Build 0:fa2de1b79154 672 {
Azure.IoT Build 0:fa2de1b79154 673 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
Azure.IoT Build 0:fa2de1b79154 674
Azure.IoT Build 0:fa2de1b79154 675 if (tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN)
Azure.IoT Build 0:fa2de1b79154 676 {
Azure.IoT Build 6:c55b013dfc2a 677 LogError("Invalid state encountered.");
AzureIoTClient 21:b92006c5b9ff 678 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 679 }
Azure.IoT Build 0:fa2de1b79154 680 else
Azure.IoT Build 0:fa2de1b79154 681 {
Azure.IoT Build 0:fa2de1b79154 682 tls_io_instance->on_bytes_received = on_bytes_received;
Azure.IoT Build 0:fa2de1b79154 683 tls_io_instance->on_bytes_received_context = on_bytes_received_context;
Azure.IoT Build 0:fa2de1b79154 684
Azure.IoT Build 0:fa2de1b79154 685 tls_io_instance->on_io_open_complete = on_io_open_complete;
Azure.IoT Build 0:fa2de1b79154 686 tls_io_instance->on_io_open_complete_context = on_io_open_complete_context;
Azure.IoT Build 0:fa2de1b79154 687
Azure.IoT Build 0:fa2de1b79154 688 tls_io_instance->on_io_error = on_io_error;
Azure.IoT Build 0:fa2de1b79154 689 tls_io_instance->on_io_error_context = on_io_error_context;
Azure.IoT Build 0:fa2de1b79154 690
Azure.IoT Build 0:fa2de1b79154 691 tls_io_instance->tlsio_state = TLSIO_STATE_OPENING_UNDERLYING_IO;
Azure.IoT Build 0:fa2de1b79154 692
Azure.IoT Build 6:c55b013dfc2a 693 if (create_wolfssl_instance(tls_io_instance) != 0)
Azure.IoT Build 6:c55b013dfc2a 694 {
AzureIoTClient 19:2e0811512ceb 695 LogError("Cannot create wolfssl instance.");
Azure.IoT Build 6:c55b013dfc2a 696 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
AzureIoTClient 21:b92006c5b9ff 697 result = __FAILURE__;
Azure.IoT Build 6:c55b013dfc2a 698 }
Azure.IoT Build 6:c55b013dfc2a 699 else if (xio_open(tls_io_instance->socket_io, on_underlying_io_open_complete, tls_io_instance, on_underlying_io_bytes_received, tls_io_instance, on_underlying_io_error, tls_io_instance) != 0)
Azure.IoT Build 0:fa2de1b79154 700 {
AzureIoTClient 19:2e0811512ceb 701 LogError("Cannot open the underlying IO.");
Azure.IoT Build 0:fa2de1b79154 702 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
AzureIoTClient 21:b92006c5b9ff 703 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 704 }
Azure.IoT Build 0:fa2de1b79154 705 else
Azure.IoT Build 0:fa2de1b79154 706 {
Azure.IoT Build 6:c55b013dfc2a 707 // The state can get changed in the on_underlying_io_open_complete
AzureIoTClient 15:956c6d205aa7 708 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN)
Azure.IoT Build 0:fa2de1b79154 709 {
Azure.IoT Build 6:c55b013dfc2a 710 LogError("Failed to connect to server. The certificates may not be correct.");
AzureIoTClient 21:b92006c5b9ff 711 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 712 }
Azure.IoT Build 0:fa2de1b79154 713 else
Azure.IoT Build 0:fa2de1b79154 714 {
AzureIoTClient 15:956c6d205aa7 715 result = 0;
Azure.IoT Build 0:fa2de1b79154 716 }
Azure.IoT Build 0:fa2de1b79154 717 }
Azure.IoT Build 0:fa2de1b79154 718 }
Azure.IoT Build 0:fa2de1b79154 719 }
Azure.IoT Build 0:fa2de1b79154 720
Azure.IoT Build 0:fa2de1b79154 721 return result;
Azure.IoT Build 0:fa2de1b79154 722 }
Azure.IoT Build 0:fa2de1b79154 723
Azure.IoT Build 0:fa2de1b79154 724 int tlsio_wolfssl_close(CONCRETE_IO_HANDLE tls_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context)
Azure.IoT Build 0:fa2de1b79154 725 {
Azure.IoT Build 0:fa2de1b79154 726 int result = 0;
Azure.IoT Build 0:fa2de1b79154 727
Azure.IoT Build 0:fa2de1b79154 728 if (tls_io == NULL)
Azure.IoT Build 0:fa2de1b79154 729 {
AzureIoTClient 19:2e0811512ceb 730 LogError("NULL tls_io handle.");
AzureIoTClient 21:b92006c5b9ff 731 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 732 }
Azure.IoT Build 0:fa2de1b79154 733 else
Azure.IoT Build 0:fa2de1b79154 734 {
Azure.IoT Build 0:fa2de1b79154 735 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
Azure.IoT Build 0:fa2de1b79154 736
Azure.IoT Build 0:fa2de1b79154 737 if ((tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN) ||
Azure.IoT Build 0:fa2de1b79154 738 (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING))
Azure.IoT Build 0:fa2de1b79154 739 {
AzureIoTClient 19:2e0811512ceb 740 LogError("Close called while not open.");
AzureIoTClient 21:b92006c5b9ff 741 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 742 }
Azure.IoT Build 0:fa2de1b79154 743 else
Azure.IoT Build 0:fa2de1b79154 744 {
Azure.IoT Build 0:fa2de1b79154 745 tls_io_instance->tlsio_state = TLSIO_STATE_CLOSING;
Azure.IoT Build 0:fa2de1b79154 746 tls_io_instance->on_io_close_complete = on_io_close_complete;
Azure.IoT Build 0:fa2de1b79154 747 tls_io_instance->on_io_close_complete_context = callback_context;
Azure.IoT Build 0:fa2de1b79154 748
Azure.IoT Build 0:fa2de1b79154 749 if (xio_close(tls_io_instance->socket_io, on_underlying_io_close_complete, tls_io_instance) != 0)
Azure.IoT Build 0:fa2de1b79154 750 {
AzureIoTClient 19:2e0811512ceb 751 LogError("xio_close failed.");
AzureIoTClient 21:b92006c5b9ff 752 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 753 }
Azure.IoT Build 0:fa2de1b79154 754 else
Azure.IoT Build 0:fa2de1b79154 755 {
Azure.IoT Build 6:c55b013dfc2a 756 destroy_wolfssl_instance(tls_io_instance);
Azure.IoT Build 0:fa2de1b79154 757 result = 0;
Azure.IoT Build 0:fa2de1b79154 758 }
Azure.IoT Build 0:fa2de1b79154 759 }
Azure.IoT Build 0:fa2de1b79154 760 }
Azure.IoT Build 0:fa2de1b79154 761
Azure.IoT Build 0:fa2de1b79154 762 return result;
Azure.IoT Build 0:fa2de1b79154 763 }
Azure.IoT Build 0:fa2de1b79154 764
Azure.IoT Build 0:fa2de1b79154 765 int tlsio_wolfssl_send(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
Azure.IoT Build 0:fa2de1b79154 766 {
Azure.IoT Build 0:fa2de1b79154 767 int result;
Azure.IoT Build 0:fa2de1b79154 768
Azure.IoT Build 0:fa2de1b79154 769 if (tls_io == NULL)
Azure.IoT Build 0:fa2de1b79154 770 {
AzureIoTClient 19:2e0811512ceb 771 LogError("NULL tls_io handle");
AzureIoTClient 21:b92006c5b9ff 772 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 773 }
Azure.IoT Build 0:fa2de1b79154 774 else
Azure.IoT Build 0:fa2de1b79154 775 {
Azure.IoT Build 0:fa2de1b79154 776 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
Azure.IoT Build 0:fa2de1b79154 777
Azure.IoT Build 0:fa2de1b79154 778 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN)
Azure.IoT Build 0:fa2de1b79154 779 {
AzureIoTClient 19:2e0811512ceb 780 LogError("send called while not open");
AzureIoTClient 21:b92006c5b9ff 781 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 782 }
Azure.IoT Build 0:fa2de1b79154 783 else
Azure.IoT Build 0:fa2de1b79154 784 {
Azure.IoT Build 0:fa2de1b79154 785 tls_io_instance->on_send_complete = on_send_complete;
Azure.IoT Build 0:fa2de1b79154 786 tls_io_instance->on_send_complete_callback_context = callback_context;
Azure.IoT Build 0:fa2de1b79154 787
Azure.IoT Build 0:fa2de1b79154 788 int res = wolfSSL_write(tls_io_instance->ssl, buffer, size);
AzureIoTClient 15:956c6d205aa7 789 if ((res < 0) || ((size_t)res != size)) // Best way I can think of to safely compare an int to a size_t
Azure.IoT Build 0:fa2de1b79154 790 {
AzureIoTClient 19:2e0811512ceb 791 LogError("Error writing data through WolfSSL");
AzureIoTClient 21:b92006c5b9ff 792 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 793 }
Azure.IoT Build 0:fa2de1b79154 794 else
Azure.IoT Build 0:fa2de1b79154 795 {
Azure.IoT Build 0:fa2de1b79154 796 result = 0;
Azure.IoT Build 0:fa2de1b79154 797 }
Azure.IoT Build 0:fa2de1b79154 798 }
Azure.IoT Build 0:fa2de1b79154 799 }
Azure.IoT Build 0:fa2de1b79154 800
Azure.IoT Build 0:fa2de1b79154 801 return result;
Azure.IoT Build 0:fa2de1b79154 802 }
Azure.IoT Build 0:fa2de1b79154 803
Azure.IoT Build 0:fa2de1b79154 804 void tlsio_wolfssl_dowork(CONCRETE_IO_HANDLE tls_io)
Azure.IoT Build 0:fa2de1b79154 805 {
AzureIoTClient 19:2e0811512ceb 806 if (tls_io == NULL)
AzureIoTClient 19:2e0811512ceb 807 {
AzureIoTClient 19:2e0811512ceb 808 LogError("NULL tls_io");
AzureIoTClient 19:2e0811512ceb 809 }
AzureIoTClient 19:2e0811512ceb 810 else
Azure.IoT Build 0:fa2de1b79154 811 {
Azure.IoT Build 0:fa2de1b79154 812 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
Azure.IoT Build 0:fa2de1b79154 813
Azure.IoT Build 0:fa2de1b79154 814 if ((tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN) &&
Azure.IoT Build 0:fa2de1b79154 815 (tls_io_instance->tlsio_state != TLSIO_STATE_ERROR))
Azure.IoT Build 0:fa2de1b79154 816 {
Azure.IoT Build 0:fa2de1b79154 817 decode_ssl_received_bytes(tls_io_instance);
Azure.IoT Build 0:fa2de1b79154 818 xio_dowork(tls_io_instance->socket_io);
Azure.IoT Build 0:fa2de1b79154 819 }
Azure.IoT Build 0:fa2de1b79154 820 }
Azure.IoT Build 0:fa2de1b79154 821 }
Azure.IoT Build 0:fa2de1b79154 822
Azure.IoT Build 0:fa2de1b79154 823 const IO_INTERFACE_DESCRIPTION* tlsio_wolfssl_get_interface_description(void)
Azure.IoT Build 0:fa2de1b79154 824 {
Azure.IoT Build 0:fa2de1b79154 825 return &tlsio_wolfssl_interface_description;
Azure.IoT Build 0:fa2de1b79154 826 }
Azure.IoT Build 0:fa2de1b79154 827
AzureIoTClient 15:956c6d205aa7 828 static int process_option(char** destination, const char* name, const char* value)
AzureIoTClient 15:956c6d205aa7 829 {
AzureIoTClient 15:956c6d205aa7 830 int result;
AzureIoTClient 15:956c6d205aa7 831 if (*destination != NULL)
AzureIoTClient 15:956c6d205aa7 832 {
AzureIoTClient 15:956c6d205aa7 833 free(*destination);
AzureIoTClient 15:956c6d205aa7 834 *destination = NULL;
AzureIoTClient 15:956c6d205aa7 835 }
AzureIoTClient 15:956c6d205aa7 836 if (mallocAndStrcpy_s(destination, value) != 0)
AzureIoTClient 15:956c6d205aa7 837 {
AzureIoTClient 15:956c6d205aa7 838 LogError("unable to process option %s",name);
AzureIoTClient 21:b92006c5b9ff 839 result = __FAILURE__;
AzureIoTClient 15:956c6d205aa7 840 }
AzureIoTClient 15:956c6d205aa7 841 else
AzureIoTClient 15:956c6d205aa7 842 {
AzureIoTClient 15:956c6d205aa7 843 result = 0;
AzureIoTClient 15:956c6d205aa7 844 }
AzureIoTClient 15:956c6d205aa7 845 return result;
AzureIoTClient 19:2e0811512ceb 846 }
AzureIoTClient 15:956c6d205aa7 847
Azure.IoT Build 0:fa2de1b79154 848 int tlsio_wolfssl_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value)
Azure.IoT Build 0:fa2de1b79154 849 {
Azure.IoT Build 0:fa2de1b79154 850 int result;
Azure.IoT Build 0:fa2de1b79154 851
Azure.IoT Build 0:fa2de1b79154 852 if (tls_io == NULL || optionName == NULL)
Azure.IoT Build 0:fa2de1b79154 853 {
AzureIoTClient 19:2e0811512ceb 854 LogError("Bad arguments, tls_io = %p, optionName = %p", tls_io, optionName);
AzureIoTClient 21:b92006c5b9ff 855 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 856 }
Azure.IoT Build 0:fa2de1b79154 857 else
Azure.IoT Build 0:fa2de1b79154 858 {
Azure.IoT Build 0:fa2de1b79154 859 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;
Azure.IoT Build 0:fa2de1b79154 860
Azure.IoT Build 0:fa2de1b79154 861 if (strcmp("TrustedCerts", optionName) == 0)
Azure.IoT Build 0:fa2de1b79154 862 {
AzureIoTClient 15:956c6d205aa7 863 result = process_option(&tls_io_instance->certificate, optionName, value);
AzureIoTClient 15:956c6d205aa7 864 }
AzureIoTClient 15:956c6d205aa7 865 else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0)
AzureIoTClient 15:956c6d205aa7 866 {
AzureIoTClient 15:956c6d205aa7 867 result = process_option(&tls_io_instance->x509certificate, optionName, value);
AzureIoTClient 15:956c6d205aa7 868 }
AzureIoTClient 15:956c6d205aa7 869 else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0)
AzureIoTClient 15:956c6d205aa7 870 {
AzureIoTClient 15:956c6d205aa7 871 result = process_option(&tls_io_instance->x509privatekey, optionName, value);
AzureIoTClient 15:956c6d205aa7 872 }
AzureIoTClient 15:956c6d205aa7 873 else
AzureIoTClient 15:956c6d205aa7 874 {
AzureIoTClient 15:956c6d205aa7 875 if (tls_io_instance->socket_io == NULL)
Azure.IoT Build 0:fa2de1b79154 876 {
AzureIoTClient 19:2e0811512ceb 877 LogError("NULL underlying IO handle");
AzureIoTClient 21:b92006c5b9ff 878 result = __FAILURE__;
Azure.IoT Build 0:fa2de1b79154 879 }
Azure.IoT Build 0:fa2de1b79154 880 else
Azure.IoT Build 0:fa2de1b79154 881 {
AzureIoTClient 15:956c6d205aa7 882 result = xio_setoption(tls_io_instance->socket_io, optionName, value);
Azure.IoT Build 0:fa2de1b79154 883 }
Azure.IoT Build 0:fa2de1b79154 884 }
Azure.IoT Build 0:fa2de1b79154 885 }
Azure.IoT Build 0:fa2de1b79154 886
Azure.IoT Build 0:fa2de1b79154 887 return result;
AzureIoTClient 10:1be0bc9a9deb 888 }