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