Azure IoT common library

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Committer:
AzureIoTClient
Date:
Wed Nov 16 21:38:39 2016 -0800
Revision:
15:956c6d205aa7
Parent:
10:1be0bc9a9deb
Child:
19:2e0811512ceb
1.0.10

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