WIP. send a large constant string twice a second, in order to test out the transport with something indicative of our required load.

Dependencies:   FXOS8700CQ NTPClient azure_umqtt_c iothub_mqtt_transport mbed-rtos mbed wolfSSL Socket lwip-eth lwip-sys lwip

Fork of FXOS8700CQ_To_Azure_IoT by Mark Radbourne

Committer:
julianhigginson
Date:
Thu Jan 05 23:40:24 2017 +0000
Revision:
7:0d1a0fe537dc
Parent:
3:c0556ff7b8e3
modified dummy message for minimal data transport

Who changed what in which revision?

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