Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed
Fork of iothub_client_sample_amqp by
tlsio_wolfssl.c
00001 // Copyright (c) Microsoft. All rights reserved. 00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 00003 00004 #include "azure_c_shared_utility/tlsio_mbedconfig.h" 00005 00006 #ifdef USE_WOLF_SSL 00007 00008 #include <stdlib.h> 00009 #ifdef _CRTDBG_MAP_ALLOC 00010 #include <crtdbg.h> 00011 #endif 00012 00013 #include "wolfssl/ssl.h" 00014 #include "wolfssl/error-ssl.h" 00015 #include <stdio.h> 00016 #include <stdbool.h> 00017 #include <string.h> 00018 #include "azure_c_shared_utility/tlsio.h" 00019 #include "azure_c_shared_utility/tlsio_wolfssl.h" 00020 #include "azure_c_shared_utility/socketio.h" 00021 #include "azure_c_shared_utility/crt_abstractions.h" 00022 #include "azure_c_shared_utility/xlogging.h" 00023 #include "azure_c_shared_utility/shared_util_options.h" 00024 00025 00026 typedef enum TLSIO_STATE_ENUM_TAG 00027 { 00028 TLSIO_STATE_NOT_OPEN, 00029 TLSIO_STATE_OPENING_UNDERLYING_IO, 00030 TLSIO_STATE_IN_HANDSHAKE, 00031 TLSIO_STATE_OPEN, 00032 TLSIO_STATE_CLOSING, 00033 TLSIO_STATE_ERROR 00034 } TLSIO_STATE_ENUM; 00035 00036 typedef struct TLS_IO_INSTANCE_TAG 00037 { 00038 XIO_HANDLE socket_io; 00039 ON_BYTES_RECEIVED on_bytes_received; 00040 ON_IO_OPEN_COMPLETE on_io_open_complete; 00041 ON_IO_CLOSE_COMPLETE on_io_close_complete; 00042 ON_IO_ERROR on_io_error; 00043 void* on_bytes_received_context; 00044 void* on_io_open_complete_context; 00045 void* on_io_close_complete_context; 00046 void* on_io_error_context; 00047 WOLFSSL* ssl; 00048 WOLFSSL_CTX* ssl_context; 00049 TLSIO_STATE_ENUM tlsio_state; 00050 unsigned char* socket_io_read_bytes; 00051 size_t socket_io_read_byte_count; 00052 ON_SEND_COMPLETE on_send_complete; 00053 void* on_send_complete_callback_context; 00054 char* certificate; 00055 char* x509certificate; 00056 char* x509privatekey; 00057 char* hostname; 00058 int port; 00059 } TLS_IO_INSTANCE; 00060 00061 /*this function will clone an option given by name and value*/ 00062 static void* tlsio_wolfssl_CloneOption(const char* name, const void* value) 00063 { 00064 void* result; 00065 if ((name == NULL) || (value == NULL)) 00066 { 00067 LogError("invalid parameter detected: const char* name=%p, const void* value=%p", name, value); 00068 result = NULL; 00069 } 00070 else 00071 { 00072 if (strcmp(name, "TrustedCerts") == 0) 00073 { 00074 if (mallocAndStrcpy_s((char**)&result, value) != 0) 00075 { 00076 LogError("unable to mallocAndStrcpy_s TrustedCerts value"); 00077 result = NULL; 00078 } 00079 else 00080 { 00081 /*return as is*/ 00082 } 00083 } 00084 else if (strcmp(name, SU_OPTION_X509_CERT) == 0) 00085 { 00086 if (mallocAndStrcpy_s((char**)&result, value) != 0) 00087 { 00088 LogError("unable to mallocAndStrcpy_s x509certificate value"); 00089 result = NULL; 00090 } 00091 else 00092 { 00093 /*return as is*/ 00094 } 00095 } 00096 else if (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0) 00097 { 00098 if (mallocAndStrcpy_s((char**)&result, value) != 0) 00099 { 00100 LogError("unable to mallocAndStrcpy_s x509privatekey value"); 00101 result = NULL; 00102 } 00103 else 00104 { 00105 /*return as is*/ 00106 } 00107 } 00108 else 00109 { 00110 LogError("not handled option : %s", name); 00111 result = NULL; 00112 } 00113 } 00114 return result; 00115 } 00116 00117 /*this function destroys an option previously created*/ 00118 static void tlsio_wolfssl_DestroyOption(const char* name, const void* value) 00119 { 00120 /*since all options for this layer are actually string copies., disposing of one is just calling free*/ 00121 if ((name == NULL) || (value == NULL)) 00122 { 00123 LogError("invalid parameter detected: const char* name=%p, const void* value=%p", name, value); 00124 } 00125 else 00126 { 00127 if ((strcmp(name, "TrustedCerts") == 0) || 00128 (strcmp(name, SU_OPTION_X509_CERT) == 0) || 00129 (strcmp(name, SU_OPTION_X509_PRIVATE_KEY) == 0)) 00130 { 00131 free((void*)value); 00132 } 00133 else 00134 { 00135 LogError("not handled option : %s", name); 00136 } 00137 } 00138 } 00139 00140 static OPTIONHANDLER_HANDLE tlsio_wolfssl_retrieveoptions(CONCRETE_IO_HANDLE tls_io) 00141 { 00142 OPTIONHANDLER_HANDLE result; 00143 (void)tls_io; 00144 00145 result = OptionHandler_Create(tlsio_wolfssl_CloneOption, tlsio_wolfssl_DestroyOption, tlsio_wolfssl_setoption); 00146 if (result == NULL) 00147 { 00148 /*return as is*/ 00149 } 00150 else 00151 { 00152 /*insert here work to add the options to "result" handle*/ 00153 } 00154 return result; 00155 } 00156 00157 static const IO_INTERFACE_DESCRIPTION tlsio_wolfssl_interface_description = 00158 { 00159 tlsio_wolfssl_retrieveoptions, 00160 tlsio_wolfssl_create, 00161 tlsio_wolfssl_destroy, 00162 tlsio_wolfssl_open, 00163 tlsio_wolfssl_close, 00164 tlsio_wolfssl_send, 00165 tlsio_wolfssl_dowork, 00166 tlsio_wolfssl_setoption 00167 }; 00168 00169 static void indicate_error(TLS_IO_INSTANCE* tls_io_instance) 00170 { 00171 if (tls_io_instance->on_io_error != NULL) 00172 { 00173 tls_io_instance->on_io_error(tls_io_instance->on_io_error_context); 00174 } 00175 } 00176 00177 static void indicate_open_complete(TLS_IO_INSTANCE* tls_io_instance, IO_OPEN_RESULT open_result) 00178 { 00179 if (tls_io_instance->on_io_open_complete != NULL) 00180 { 00181 tls_io_instance->on_io_open_complete(tls_io_instance->on_io_open_complete_context, open_result); 00182 } 00183 } 00184 00185 static int decode_ssl_received_bytes(TLS_IO_INSTANCE* tls_io_instance) 00186 { 00187 int result = 0; 00188 unsigned char buffer[64]; 00189 00190 int rcv_bytes = 1; 00191 while (rcv_bytes > 0) 00192 { 00193 rcv_bytes = wolfSSL_read(tls_io_instance->ssl, buffer, sizeof(buffer)); 00194 if (rcv_bytes > 0) 00195 { 00196 if (tls_io_instance->on_bytes_received != NULL) 00197 { 00198 tls_io_instance->on_bytes_received(tls_io_instance->on_bytes_received_context, buffer, rcv_bytes); 00199 } 00200 } 00201 } 00202 00203 return result; 00204 } 00205 00206 static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_result) 00207 { 00208 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00209 00210 if (open_result != IO_OPEN_OK) 00211 { 00212 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00213 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR); 00214 } 00215 else 00216 { 00217 int res; 00218 tls_io_instance->tlsio_state = TLSIO_STATE_IN_HANDSHAKE; 00219 00220 res = wolfSSL_connect(tls_io_instance->ssl); 00221 if (res != SSL_SUCCESS) 00222 { 00223 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR); 00224 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00225 } 00226 } 00227 } 00228 00229 static void on_underlying_io_bytes_received(void* context, const unsigned char* buffer, size_t size) 00230 { 00231 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00232 00233 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); 00234 if (new_socket_io_read_bytes == NULL) 00235 { 00236 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00237 indicate_error(tls_io_instance); 00238 } 00239 else 00240 { 00241 tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes; 00242 (void)memcpy(tls_io_instance->socket_io_read_bytes + tls_io_instance->socket_io_read_byte_count, buffer, size); 00243 tls_io_instance->socket_io_read_byte_count += size; 00244 } 00245 } 00246 00247 static void on_underlying_io_error(void* context) 00248 { 00249 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00250 00251 switch (tls_io_instance->tlsio_state) 00252 { 00253 default: 00254 case TLSIO_STATE_NOT_OPEN: 00255 case TLSIO_STATE_ERROR: 00256 break; 00257 00258 case TLSIO_STATE_OPENING_UNDERLYING_IO: 00259 case TLSIO_STATE_IN_HANDSHAKE: 00260 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00261 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR); 00262 break; 00263 00264 case TLSIO_STATE_OPEN: 00265 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00266 indicate_error(tls_io_instance); 00267 break; 00268 } 00269 } 00270 00271 static void on_underlying_io_close_complete(void* context) 00272 { 00273 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00274 00275 if (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING) 00276 { 00277 if (tls_io_instance->on_io_close_complete != NULL) 00278 { 00279 tls_io_instance->on_io_close_complete(tls_io_instance->on_io_close_complete_context); 00280 } 00281 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN; 00282 } 00283 } 00284 00285 static int on_io_recv(WOLFSSL *ssl, char *buf, int sz, void *context) 00286 { 00287 int result; 00288 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00289 unsigned char* new_socket_io_read_bytes; 00290 00291 (void)ssl; 00292 while (tls_io_instance->socket_io_read_byte_count == 0) 00293 { 00294 xio_dowork(tls_io_instance->socket_io); 00295 if (tls_io_instance->tlsio_state != TLSIO_STATE_IN_HANDSHAKE) 00296 { 00297 break; 00298 } 00299 } 00300 00301 result = tls_io_instance->socket_io_read_byte_count; 00302 if (result > sz) 00303 { 00304 result = sz; 00305 } 00306 00307 if (result > 0) 00308 { 00309 (void)memcpy(buf, tls_io_instance->socket_io_read_bytes, result); 00310 (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); 00311 tls_io_instance->socket_io_read_byte_count -= result; 00312 if (tls_io_instance->socket_io_read_byte_count > 0) 00313 { 00314 new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count); 00315 if (new_socket_io_read_bytes != NULL) 00316 { 00317 tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes; 00318 } 00319 } 00320 else 00321 { 00322 free(tls_io_instance->socket_io_read_bytes); 00323 tls_io_instance->socket_io_read_bytes = NULL; 00324 } 00325 } 00326 00327 if ((result == 0) && (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN)) 00328 { 00329 result = WOLFSSL_CBIO_ERR_WANT_READ; 00330 } 00331 else if ((result == 0) && tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING) 00332 { 00333 result = WOLFSSL_CBIO_ERR_CONN_CLOSE; 00334 } 00335 00336 return result; 00337 } 00338 00339 static int on_io_send(WOLFSSL *ssl, char *buf, int sz, void *context) 00340 { 00341 int result; 00342 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00343 00344 (void)ssl; 00345 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) 00346 { 00347 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00348 indicate_error(tls_io_instance); 00349 result = 0; 00350 } 00351 else 00352 { 00353 result = sz; 00354 } 00355 00356 return result; 00357 } 00358 00359 static int on_handshake_done(WOLFSSL* ssl, void* context) 00360 { 00361 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00362 (void)ssl; 00363 if (tls_io_instance->tlsio_state == TLSIO_STATE_IN_HANDSHAKE) 00364 { 00365 tls_io_instance->tlsio_state = TLSIO_STATE_OPEN; 00366 indicate_open_complete(tls_io_instance, IO_OPEN_OK); 00367 } 00368 00369 return 0; 00370 } 00371 00372 static int add_certificate_to_store(TLS_IO_INSTANCE* tls_io_instance) 00373 { 00374 int result; 00375 if (tls_io_instance->certificate != NULL) 00376 { 00377 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); 00378 if (res != SSL_SUCCESS) 00379 { 00380 result = __LINE__; 00381 } 00382 else 00383 { 00384 result = 0; 00385 } 00386 } 00387 else 00388 { 00389 result = 0; 00390 } 00391 return result; 00392 } 00393 00394 static int x509_wolfssl_add_credentials(WOLFSSL* ssl, char* x509certificate, char* x509privatekey) { 00395 00396 int result; 00397 00398 if (wolfSSL_use_certificate_buffer(ssl, (unsigned char*)x509certificate, strlen(x509certificate) + 1, SSL_FILETYPE_PEM) != SSL_SUCCESS) 00399 { 00400 LogError("unable to load x509 client certificate"); 00401 result = __LINE__; 00402 } 00403 else if (wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)x509privatekey, strlen(x509privatekey) + 1, SSL_FILETYPE_PEM) != SSL_SUCCESS) 00404 { 00405 LogError("unable to load x509 client private key"); 00406 result = __LINE__; 00407 } 00408 #ifdef HAVE_SECURE_RENEGOTIATION 00409 else if (wolfSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS) { 00410 LogError("unable to enable secure renegotiation"); 00411 result = __LINE__; 00412 } 00413 #endif 00414 else 00415 { 00416 result = 0; 00417 } 00418 return result; 00419 } 00420 00421 static void destroy_wolfssl_instance(TLS_IO_INSTANCE* tls_io_instance) 00422 { 00423 wolfSSL_free(tls_io_instance->ssl); 00424 } 00425 00426 static int create_wolfssl_instance(TLS_IO_INSTANCE* tls_io_instance) 00427 { 00428 int result; 00429 00430 if (add_certificate_to_store(tls_io_instance) != 0) 00431 { 00432 wolfSSL_CTX_free(tls_io_instance->ssl_context); 00433 result = __LINE__; 00434 } 00435 else 00436 { 00437 tls_io_instance->ssl = wolfSSL_new(tls_io_instance->ssl_context); 00438 if (tls_io_instance->ssl == NULL) 00439 { 00440 wolfSSL_CTX_free(tls_io_instance->ssl_context); 00441 result = __LINE__; 00442 } 00443 /*x509 authentication can only be build before underlying connection is realized*/ 00444 else if ((tls_io_instance->x509certificate != NULL) && 00445 (tls_io_instance->x509privatekey != NULL) && 00446 (x509_wolfssl_add_credentials(tls_io_instance->ssl, tls_io_instance->x509certificate, tls_io_instance->x509privatekey) != 0)) 00447 { 00448 destroy_wolfssl_instance(tls_io_instance); 00449 tls_io_instance->ssl = NULL; 00450 wolfSSL_CTX_free(tls_io_instance->ssl_context); 00451 tls_io_instance->ssl_context = NULL; 00452 LogError("unable to use x509 authentication"); 00453 result = __LINE__; 00454 } 00455 00456 else 00457 { 00458 tls_io_instance->socket_io_read_bytes = NULL; 00459 tls_io_instance->socket_io_read_byte_count = 0; 00460 tls_io_instance->on_send_complete = NULL; 00461 tls_io_instance->on_send_complete_callback_context = NULL; 00462 00463 wolfSSL_set_using_nonblock(tls_io_instance->ssl, 1); 00464 wolfSSL_SetIOSend(tls_io_instance->ssl_context, on_io_send); 00465 wolfSSL_SetIORecv(tls_io_instance->ssl_context, on_io_recv); 00466 wolfSSL_SetHsDoneCb(tls_io_instance->ssl, on_handshake_done, tls_io_instance); 00467 wolfSSL_SetIOWriteCtx(tls_io_instance->ssl, tls_io_instance); 00468 wolfSSL_SetIOReadCtx(tls_io_instance->ssl, tls_io_instance); 00469 00470 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN; 00471 result = 0; 00472 } 00473 } 00474 return result; 00475 } 00476 00477 int tlsio_wolfssl_init(void) 00478 { 00479 (void)wolfSSL_library_init(); 00480 wolfSSL_load_error_strings(); 00481 00482 return 0; 00483 } 00484 00485 void tlsio_wolfssl_deinit(void) 00486 { 00487 } 00488 00489 CONCRETE_IO_HANDLE tlsio_wolfssl_create(void* io_create_parameters) 00490 { 00491 TLSIO_CONFIG* tls_io_config = io_create_parameters; 00492 TLS_IO_INSTANCE* result; 00493 00494 if (tls_io_config == NULL) 00495 { 00496 result = NULL; 00497 } 00498 else 00499 { 00500 result = (TLS_IO_INSTANCE*)malloc(sizeof(TLS_IO_INSTANCE)); 00501 if (result != NULL) 00502 { 00503 memset(result, 0, sizeof(TLS_IO_INSTANCE)); 00504 mallocAndStrcpy_s(&result->hostname, tls_io_config->hostname); 00505 result->port = tls_io_config->port; 00506 00507 result->socket_io_read_bytes = 0; 00508 result->socket_io_read_byte_count = 0; 00509 result->socket_io = NULL; 00510 00511 result->ssl = NULL; 00512 result->ssl_context = NULL; 00513 result->certificate = NULL; 00514 result->x509certificate = NULL; 00515 result->x509privatekey = NULL; 00516 00517 result->on_bytes_received = NULL; 00518 result->on_bytes_received_context = NULL; 00519 00520 result->on_io_open_complete = NULL; 00521 result->on_io_open_complete_context = NULL; 00522 00523 result->on_io_close_complete = NULL; 00524 result->on_io_close_complete_context = NULL; 00525 00526 result->on_io_error = NULL; 00527 result->on_io_error_context = NULL; 00528 00529 result->tlsio_state = TLSIO_STATE_NOT_OPEN; 00530 00531 result->ssl_context = wolfSSL_CTX_new(wolfTLSv1_client_method()); 00532 if (result->ssl_context == NULL) 00533 { 00534 free(result); 00535 result = NULL; 00536 } 00537 else 00538 { 00539 const IO_INTERFACE_DESCRIPTION* socket_io_interface = socketio_get_interface_description(); 00540 if (socket_io_interface == NULL) 00541 { 00542 wolfSSL_CTX_free(result->ssl_context); 00543 free(result); 00544 result = NULL; 00545 } 00546 else 00547 { 00548 SOCKETIO_CONFIG socketio_config; 00549 socketio_config.hostname = result->hostname; 00550 socketio_config.port = result->port; 00551 socketio_config.accepted_socket = NULL; 00552 00553 result->socket_io = xio_create(socket_io_interface, &socketio_config); 00554 if (result->socket_io == NULL) 00555 { 00556 LogError("Failure connecting to underlying socket_io"); 00557 wolfSSL_CTX_free(result->ssl_context); 00558 free(result); 00559 result = NULL; 00560 } 00561 } 00562 } 00563 00564 00565 } 00566 } 00567 00568 return result; 00569 } 00570 00571 void tlsio_wolfssl_destroy(CONCRETE_IO_HANDLE tls_io) 00572 { 00573 if (tls_io != NULL) 00574 { 00575 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00576 if (tls_io_instance->socket_io_read_bytes != NULL) 00577 { 00578 free(tls_io_instance->socket_io_read_bytes); 00579 } 00580 00581 if (tls_io_instance->certificate != NULL) 00582 { 00583 free(tls_io_instance->certificate); 00584 tls_io_instance->certificate = NULL; 00585 } 00586 if (tls_io_instance->x509certificate != NULL) 00587 { 00588 free(tls_io_instance->x509certificate); 00589 tls_io_instance->x509certificate = NULL; 00590 } 00591 if (tls_io_instance->x509privatekey != NULL) 00592 { 00593 free(tls_io_instance->x509privatekey); 00594 tls_io_instance->x509privatekey = NULL; 00595 } 00596 wolfSSL_CTX_free(tls_io_instance->ssl_context); 00597 xio_destroy(tls_io_instance->socket_io); 00598 free(tls_io); 00599 } 00600 } 00601 00602 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) 00603 { 00604 int result; 00605 00606 if (tls_io == NULL) 00607 { 00608 result = __LINE__; 00609 } 00610 else 00611 { 00612 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00613 00614 if (tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN) 00615 { 00616 LogError("Invalid state encountered."); 00617 result = __LINE__; 00618 } 00619 else 00620 { 00621 tls_io_instance->on_bytes_received = on_bytes_received; 00622 tls_io_instance->on_bytes_received_context = on_bytes_received_context; 00623 00624 tls_io_instance->on_io_open_complete = on_io_open_complete; 00625 tls_io_instance->on_io_open_complete_context = on_io_open_complete_context; 00626 00627 tls_io_instance->on_io_error = on_io_error; 00628 tls_io_instance->on_io_error_context = on_io_error_context; 00629 00630 tls_io_instance->tlsio_state = TLSIO_STATE_OPENING_UNDERLYING_IO; 00631 00632 if (create_wolfssl_instance(tls_io_instance) != 0) 00633 { 00634 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN; 00635 result = __LINE__; 00636 } 00637 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) 00638 { 00639 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN; 00640 result = __LINE__; 00641 } 00642 else 00643 { 00644 // The state can get changed in the on_underlying_io_open_complete 00645 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN) 00646 { 00647 LogError("Failed to connect to server. The certificates may not be correct."); 00648 result = __LINE__; 00649 } 00650 else 00651 { 00652 result = 0; 00653 } 00654 } 00655 } 00656 } 00657 00658 return result; 00659 } 00660 00661 int tlsio_wolfssl_close(CONCRETE_IO_HANDLE tls_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context) 00662 { 00663 int result = 0; 00664 00665 if (tls_io == NULL) 00666 { 00667 result = __LINE__; 00668 } 00669 else 00670 { 00671 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00672 00673 if ((tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN) || 00674 (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING)) 00675 { 00676 result = __LINE__; 00677 } 00678 else 00679 { 00680 tls_io_instance->tlsio_state = TLSIO_STATE_CLOSING; 00681 tls_io_instance->on_io_close_complete = on_io_close_complete; 00682 tls_io_instance->on_io_close_complete_context = callback_context; 00683 00684 if (xio_close(tls_io_instance->socket_io, on_underlying_io_close_complete, tls_io_instance) != 0) 00685 { 00686 result = __LINE__; 00687 } 00688 else 00689 { 00690 destroy_wolfssl_instance(tls_io_instance); 00691 result = 0; 00692 } 00693 } 00694 } 00695 00696 return result; 00697 } 00698 00699 int tlsio_wolfssl_send(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context) 00700 { 00701 int result; 00702 00703 if (tls_io == NULL) 00704 { 00705 result = __LINE__; 00706 } 00707 else 00708 { 00709 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00710 00711 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN) 00712 { 00713 result = __LINE__; 00714 } 00715 else 00716 { 00717 tls_io_instance->on_send_complete = on_send_complete; 00718 tls_io_instance->on_send_complete_callback_context = callback_context; 00719 00720 int res = wolfSSL_write(tls_io_instance->ssl, buffer, size); 00721 if ((res < 0) || ((size_t)res != size)) // Best way I can think of to safely compare an int to a size_t 00722 { 00723 result = __LINE__; 00724 } 00725 else 00726 { 00727 result = 0; 00728 } 00729 } 00730 } 00731 00732 return result; 00733 } 00734 00735 void tlsio_wolfssl_dowork(CONCRETE_IO_HANDLE tls_io) 00736 { 00737 if (tls_io != NULL) 00738 { 00739 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00740 00741 if ((tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN) && 00742 (tls_io_instance->tlsio_state != TLSIO_STATE_ERROR)) 00743 { 00744 decode_ssl_received_bytes(tls_io_instance); 00745 xio_dowork(tls_io_instance->socket_io); 00746 } 00747 } 00748 } 00749 00750 const IO_INTERFACE_DESCRIPTION* tlsio_wolfssl_get_interface_description(void) 00751 { 00752 return &tlsio_wolfssl_interface_description; 00753 } 00754 00755 static int process_option(char** destination, const char* name, const char* value) 00756 { 00757 int result; 00758 if (*destination != NULL) 00759 { 00760 free(*destination); 00761 *destination = NULL; 00762 } 00763 if (mallocAndStrcpy_s(destination, value) != 0) 00764 { 00765 LogError("unable to process option %s",name); 00766 result = __LINE__; 00767 } 00768 else 00769 { 00770 result = 0; 00771 } 00772 return result; 00773 00774 } 00775 int tlsio_wolfssl_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value) 00776 { 00777 int result; 00778 00779 if (tls_io == NULL || optionName == NULL) 00780 { 00781 result = __LINE__; 00782 } 00783 else 00784 { 00785 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00786 00787 if (strcmp("TrustedCerts", optionName) == 0) 00788 { 00789 result = process_option(&tls_io_instance->certificate, optionName, value); 00790 } 00791 else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0) 00792 { 00793 result = process_option(&tls_io_instance->x509certificate, optionName, value); 00794 } 00795 else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0) 00796 { 00797 result = process_option(&tls_io_instance->x509privatekey, optionName, value); 00798 } 00799 else 00800 { 00801 if (tls_io_instance->socket_io == NULL) 00802 { 00803 result = __LINE__; 00804 } 00805 else 00806 { 00807 result = xio_setoption(tls_io_instance->socket_io, optionName, value); 00808 } 00809 } 00810 } 00811 00812 return result; 00813 } 00814 00815 #endif /* USE_WOLF_SSL */
Generated on Tue Jul 12 2022 12:43:25 by
