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_mbedtls.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_MBED_TLS 00007 00008 #include <stdlib.h> 00009 #ifdef _CRTDBG_MAP_ALLOC 00010 #include <crtdbg.h> 00011 #endif 00012 00013 #include "mbedtls/config.h" 00014 #include "mbedtls/debug.h" 00015 #include "mbedtls/ssl.h" 00016 #include "mbedtls/entropy.h" 00017 #include "mbedtls/ctr_drbg.h" 00018 #include "mbedtls/error.h" 00019 #include "mbedtls/certs.h" 00020 #include "mbedtls/entropy_poll.h" 00021 00022 #include <stdio.h> 00023 #include <stdbool.h> 00024 #include <string.h> 00025 #include "azure_c_shared_utility/tlsio.h" 00026 #include "azure_c_shared_utility/tlsio_mbedtls.h" 00027 #include "azure_c_shared_utility/socketio.h" 00028 00029 typedef enum TLSIO_STATE_ENUM_TAG 00030 { 00031 TLSIO_STATE_NOT_OPEN, 00032 TLSIO_STATE_OPENING_UNDERLYING_IO, 00033 TLSIO_STATE_IN_HANDSHAKE, 00034 TLSIO_STATE_OPEN, 00035 TLSIO_STATE_CLOSING, 00036 TLSIO_STATE_ERROR 00037 } TLSIO_STATE_ENUM; 00038 00039 typedef struct TLS_IO_INSTANCE_TAG 00040 { 00041 XIO_HANDLE socket_io; 00042 ON_BYTES_RECEIVED on_bytes_received; 00043 ON_IO_OPEN_COMPLETE on_io_open_complete; 00044 ON_IO_CLOSE_COMPLETE on_io_close_complete; 00045 ON_IO_ERROR on_io_error; 00046 void* on_bytes_received_context; 00047 void* on_io_open_complete_context; 00048 void* on_io_close_complete_context; 00049 void* on_io_error_context; 00050 TLSIO_STATE_ENUM tlsio_state; 00051 unsigned char* socket_io_read_bytes; 00052 size_t socket_io_read_byte_count; 00053 ON_SEND_COMPLETE on_send_complete; 00054 void* on_send_complete_callback_context; 00055 mbedtls_entropy_context entropy; 00056 mbedtls_ctr_drbg_context ctr_drbg; 00057 mbedtls_ssl_context ssl; 00058 mbedtls_ssl_config config; 00059 mbedtls_x509_crt cacert; 00060 mbedtls_ssl_session ssn; 00061 } TLS_IO_INSTANCE; 00062 00063 static const IO_INTERFACE_DESCRIPTION tlsio_mbedtls_interface_description = 00064 { 00065 tlsio_mbedtls_retrieveoptions, 00066 tlsio_mbedtls_create, 00067 tlsio_mbedtls_destroy, 00068 tlsio_mbedtls_open, 00069 tlsio_mbedtls_close, 00070 tlsio_mbedtls_send, 00071 tlsio_mbedtls_dowork, 00072 tlsio_mbedtls_setoption 00073 }; 00074 00075 #if defined (MBED_TLS_DEBUG_ENABLE) 00076 void mbedtls_debug(void *ctx, int level,const char *file, int line, const char *str ) 00077 { 00078 ((void) level); 00079 printf("%s (%d): %s\r\n", file,line,str); 00080 } 00081 #endif 00082 00083 static void indicate_error(TLS_IO_INSTANCE* tls_io_instance) 00084 { 00085 if (tls_io_instance->on_io_error != NULL) 00086 { 00087 tls_io_instance->on_io_error(tls_io_instance->on_io_error_context); 00088 } 00089 } 00090 00091 static void indicate_open_complete(TLS_IO_INSTANCE* tls_io_instance, IO_OPEN_RESULT open_result) 00092 { 00093 if (tls_io_instance->on_io_open_complete != NULL) 00094 { 00095 tls_io_instance->on_io_open_complete(tls_io_instance->on_io_open_complete_context, open_result); 00096 } 00097 } 00098 00099 static int decode_ssl_received_bytes(TLS_IO_INSTANCE* tls_io_instance) 00100 { 00101 int result = 0; 00102 unsigned char buffer[64]; 00103 00104 int rcv_bytes = 1; 00105 while (rcv_bytes > 0) 00106 { 00107 rcv_bytes = mbedtls_ssl_read(&tls_io_instance->ssl, buffer, sizeof(buffer)); 00108 if (rcv_bytes > 0) 00109 { 00110 if (tls_io_instance->on_bytes_received != NULL) 00111 { 00112 tls_io_instance->on_bytes_received(tls_io_instance->on_bytes_received_context, buffer, rcv_bytes); 00113 } 00114 } 00115 } 00116 00117 return result; 00118 } 00119 00120 static int on_handshake_done(mbedtls_ssl_context* ssl, void* context) 00121 { 00122 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00123 if (tls_io_instance->tlsio_state == TLSIO_STATE_IN_HANDSHAKE) 00124 { 00125 tls_io_instance->tlsio_state = TLSIO_STATE_OPEN; 00126 indicate_open_complete(tls_io_instance, IO_OPEN_OK); 00127 } 00128 00129 return 0; 00130 } 00131 00132 static int mbedtls_connect(void* context) { 00133 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00134 int result = 0; 00135 00136 do { 00137 result = mbedtls_ssl_handshake(&tls_io_instance->ssl); 00138 } 00139 while( result == MBEDTLS_ERR_SSL_WANT_READ || result == MBEDTLS_ERR_SSL_WANT_WRITE ); 00140 00141 if(result == 0) 00142 { 00143 on_handshake_done(&tls_io_instance->ssl,(void *)tls_io_instance); 00144 } 00145 00146 return result; 00147 } 00148 00149 static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_result) 00150 { 00151 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00152 int result = 0; 00153 00154 if (open_result != IO_OPEN_OK) 00155 { 00156 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00157 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR); 00158 } 00159 else 00160 { 00161 tls_io_instance->tlsio_state = TLSIO_STATE_IN_HANDSHAKE; 00162 00163 result = mbedtls_connect(tls_io_instance); 00164 if (result != 0) 00165 { 00166 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR); 00167 } 00168 } 00169 } 00170 00171 static void on_underlying_io_bytes_received(void* context, const unsigned char* buffer, size_t size) 00172 { 00173 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00174 00175 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); 00176 if (new_socket_io_read_bytes == NULL) 00177 { 00178 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00179 indicate_error(tls_io_instance); 00180 } 00181 else 00182 { 00183 tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes; 00184 (void)memcpy(tls_io_instance->socket_io_read_bytes + tls_io_instance->socket_io_read_byte_count, buffer, size); 00185 tls_io_instance->socket_io_read_byte_count += size; 00186 } 00187 } 00188 00189 static void on_underlying_io_error(void* context) 00190 { 00191 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00192 00193 switch (tls_io_instance->tlsio_state) 00194 { 00195 default: 00196 case TLSIO_STATE_NOT_OPEN: 00197 case TLSIO_STATE_ERROR: 00198 break; 00199 00200 case TLSIO_STATE_OPENING_UNDERLYING_IO: 00201 case TLSIO_STATE_IN_HANDSHAKE: 00202 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00203 indicate_open_complete(tls_io_instance, IO_OPEN_ERROR); 00204 break; 00205 00206 case TLSIO_STATE_OPEN: 00207 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00208 indicate_error(tls_io_instance); 00209 break; 00210 } 00211 } 00212 00213 static void on_underlying_io_close_complete(void* context) 00214 { 00215 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00216 00217 if (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING) 00218 { 00219 if (tls_io_instance->on_io_close_complete != NULL) 00220 { 00221 tls_io_instance->on_io_close_complete(tls_io_instance->on_io_close_complete_context); 00222 } 00223 } 00224 } 00225 00226 static int on_io_recv(void *context,unsigned char *buf, size_t sz) 00227 { 00228 int result; 00229 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00230 unsigned char* new_socket_io_read_bytes; 00231 00232 while (tls_io_instance->socket_io_read_byte_count == 0) 00233 { 00234 xio_dowork(tls_io_instance->socket_io); 00235 if (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN) 00236 { 00237 break; 00238 } 00239 } 00240 00241 result = tls_io_instance->socket_io_read_byte_count; 00242 if (result > sz) 00243 { 00244 result = sz; 00245 } 00246 00247 if (result > 0) 00248 { 00249 (void)memcpy((void *)buf,tls_io_instance->socket_io_read_bytes, result); 00250 (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); 00251 tls_io_instance->socket_io_read_byte_count -= result; 00252 if (tls_io_instance->socket_io_read_byte_count > 0) 00253 { 00254 new_socket_io_read_bytes = (unsigned char*)realloc(tls_io_instance->socket_io_read_bytes, tls_io_instance->socket_io_read_byte_count); 00255 if (new_socket_io_read_bytes != NULL) 00256 { 00257 tls_io_instance->socket_io_read_bytes = new_socket_io_read_bytes; 00258 } 00259 } 00260 else 00261 { 00262 free(tls_io_instance->socket_io_read_bytes); 00263 tls_io_instance->socket_io_read_bytes = NULL; 00264 } 00265 } 00266 00267 if ((result == 0) && (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN)) 00268 { 00269 result = MBEDTLS_ERR_SSL_WANT_READ; 00270 } 00271 00272 return result; 00273 } 00274 00275 static int on_io_send(void *context,const unsigned char *buf, size_t sz) 00276 { 00277 int result; 00278 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)context; 00279 00280 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) 00281 { 00282 tls_io_instance->tlsio_state = TLSIO_STATE_ERROR; 00283 indicate_error(tls_io_instance); 00284 result = 0; 00285 } 00286 else 00287 { 00288 result = sz; 00289 } 00290 00291 return result; 00292 } 00293 00294 //static int tlsio_entropy_poll(void *v,unsigned char *output,size_t len,size_t *olen) 00295 int mbedtls_hardware_poll(void *v,unsigned char *output,size_t len,size_t *olen) 00296 { 00297 srand(time(NULL)); 00298 char *c = (char*)malloc(len); 00299 memset(c, 0, len); 00300 for(uint16_t i=0; i < len; i++){ 00301 c[i] = rand() % 256; 00302 } 00303 memmove(output, c, len); 00304 *olen = len; 00305 00306 free(c); 00307 return( 0 ); 00308 } 00309 00310 static void mbedtls_init(void *instance,const char *host) { 00311 TLS_IO_INSTANCE *result = (TLS_IO_INSTANCE *)instance; 00312 char *pers = "azure_iot_client"; 00313 00314 // mbedTLS initialize... 00315 mbedtls_entropy_init(&result->entropy); 00316 mbedtls_ctr_drbg_init(&result->ctr_drbg); 00317 mbedtls_ssl_init(&result->ssl); 00318 mbedtls_ssl_session_init(&result->ssn); 00319 mbedtls_ssl_config_init(&result->config); 00320 mbedtls_x509_crt_init(&result->cacert); 00321 mbedtls_entropy_add_source(&result->entropy,mbedtls_hardware_poll,NULL,128,0); 00322 mbedtls_ctr_drbg_seed(&result->ctr_drbg,mbedtls_entropy_func,&result->entropy,(const unsigned char *)pers,strlen(pers)); 00323 mbedtls_ssl_config_defaults(&result->config,MBEDTLS_SSL_IS_CLIENT,MBEDTLS_SSL_TRANSPORT_STREAM,MBEDTLS_SSL_PRESET_DEFAULT); 00324 mbedtls_ssl_conf_rng(&result->config,mbedtls_ctr_drbg_random,&result->ctr_drbg); 00325 mbedtls_ssl_conf_authmode(&result->config,MBEDTLS_SSL_VERIFY_OPTIONAL); 00326 mbedtls_ssl_conf_min_version(&result->config,MBEDTLS_SSL_MAJOR_VERSION_3,MBEDTLS_SSL_MINOR_VERSION_3); // v1.2 00327 mbedtls_ssl_set_bio(&result->ssl,instance,on_io_send,on_io_recv,NULL); 00328 mbedtls_ssl_set_hostname(&result->ssl,host); 00329 mbedtls_ssl_set_session(&result->ssl,&result->ssn); 00330 00331 #if defined (MBED_TLS_DEBUG_ENABLE) 00332 mbedtls_ssl_conf_dbg(&result->config, mbedtls_debug,stdout); 00333 mbedtls_debug_set_threshold(5); 00334 #endif 00335 00336 mbedtls_ssl_setup(&result->ssl,&result->config); 00337 } 00338 00339 OPTIONHANDLER_HANDLE tlsio_mbedtls_retrieveoptions(CONCRETE_IO_HANDLE handle) 00340 { 00341 (void)handle; 00342 return NULL; 00343 } 00344 00345 CONCRETE_IO_HANDLE tlsio_mbedtls_create(void* io_create_parameters) 00346 { 00347 LogInfo("Starting MBED TLS\r\n"); 00348 TLSIO_CONFIG* tls_io_config = io_create_parameters; 00349 TLS_IO_INSTANCE* result; 00350 00351 if (tls_io_config == NULL) 00352 { 00353 LogError("NULL tls_io_config"); 00354 result = NULL; 00355 } 00356 else 00357 { 00358 result = malloc(sizeof(TLS_IO_INSTANCE)); 00359 if (result != NULL) 00360 { 00361 SOCKETIO_CONFIG socketio_config; 00362 00363 socketio_config.hostname = tls_io_config->hostname; 00364 socketio_config.port = tls_io_config->port; 00365 socketio_config.accepted_socket = NULL; 00366 00367 result->on_bytes_received = NULL; 00368 result->on_bytes_received_context = NULL; 00369 00370 result->on_io_open_complete = NULL; 00371 result->on_io_open_complete_context = NULL; 00372 00373 result->on_io_close_complete = NULL; 00374 result->on_io_close_complete_context = NULL; 00375 00376 result->on_io_error = NULL; 00377 result->on_io_error_context = NULL; 00378 00379 const IO_INTERFACE_DESCRIPTION* socket_io_interface = socketio_get_interface_description(); 00380 if (socket_io_interface == NULL) 00381 { 00382 LogError("get socket io interface failed"); 00383 free(result); 00384 result = NULL; 00385 } 00386 else 00387 { 00388 result->socket_io = xio_create(socket_io_interface, &socketio_config); 00389 if (result->socket_io == NULL) 00390 { 00391 LogError("socket xio create failed"); 00392 free(result); 00393 result = NULL; 00394 } 00395 else 00396 { 00397 result->socket_io_read_bytes = NULL; 00398 result->socket_io_read_byte_count = 0; 00399 result->on_send_complete = NULL; 00400 result->on_send_complete_callback_context = NULL; 00401 00402 // mbeTLS initialize 00403 mbedtls_init((void *)result,tls_io_config->hostname); 00404 result->tlsio_state = TLSIO_STATE_NOT_OPEN; 00405 } 00406 } 00407 } 00408 } 00409 00410 return result; 00411 } 00412 00413 void tlsio_mbedtls_destroy(CONCRETE_IO_HANDLE tls_io) 00414 { 00415 if (tls_io != NULL) 00416 { 00417 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00418 00419 // mbedTLS cleanup... 00420 mbedtls_ssl_close_notify(&tls_io_instance->ssl); 00421 mbedtls_ssl_free(&tls_io_instance->ssl); 00422 mbedtls_ssl_config_free(&tls_io_instance->config); 00423 mbedtls_x509_crt_free(&tls_io_instance->cacert); 00424 mbedtls_ctr_drbg_free(&tls_io_instance->ctr_drbg); 00425 mbedtls_entropy_free(&tls_io_instance->entropy); 00426 00427 if (tls_io_instance->socket_io_read_bytes != NULL) 00428 { 00429 free(tls_io_instance->socket_io_read_bytes); 00430 } 00431 00432 xio_destroy(tls_io_instance->socket_io); 00433 free(tls_io); 00434 } 00435 } 00436 00437 int tlsio_mbedtls_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) 00438 { 00439 int result = 0; 00440 00441 if (tls_io == NULL) 00442 { 00443 LogError("NULL tls_io"); 00444 result = __LINE__; 00445 } 00446 else 00447 { 00448 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00449 00450 if (tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN) 00451 { 00452 LogError("IO should not be open"); 00453 result = __LINE__; 00454 } 00455 else 00456 { 00457 tls_io_instance->on_bytes_received = on_bytes_received; 00458 tls_io_instance->on_bytes_received_context = on_bytes_received_context; 00459 00460 tls_io_instance->on_io_open_complete = on_io_open_complete; 00461 tls_io_instance->on_io_open_complete_context = on_io_open_complete_context; 00462 00463 tls_io_instance->on_io_error = on_io_error; 00464 tls_io_instance->on_io_error_context = on_io_error_context; 00465 00466 tls_io_instance->tlsio_state = TLSIO_STATE_OPENING_UNDERLYING_IO; 00467 00468 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) 00469 { 00470 LogError("Underlying IO open failed"); 00471 tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN; 00472 result = __LINE__; 00473 } 00474 else 00475 { 00476 result = 0; 00477 } 00478 } 00479 } 00480 00481 return result; 00482 } 00483 00484 int tlsio_mbedtls_close(CONCRETE_IO_HANDLE tls_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context) 00485 { 00486 int result = 0; 00487 00488 if (tls_io == NULL) 00489 { 00490 result = __LINE__; 00491 } 00492 else 00493 { 00494 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00495 00496 if ((tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN) || 00497 (tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING)) 00498 { 00499 result = __LINE__; 00500 } 00501 else 00502 { 00503 tls_io_instance->tlsio_state = TLSIO_STATE_CLOSING; 00504 tls_io_instance->on_io_close_complete = on_io_close_complete; 00505 tls_io_instance->on_io_close_complete_context = callback_context; 00506 00507 if (xio_close(tls_io_instance->socket_io, on_underlying_io_close_complete, tls_io_instance) != 0) 00508 { 00509 result = __LINE__; 00510 } 00511 else 00512 { 00513 result = 0; 00514 } 00515 } 00516 } 00517 00518 return result; 00519 } 00520 00521 int tlsio_mbedtls_send(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context) 00522 { 00523 int result; 00524 00525 if (tls_io == NULL) 00526 { 00527 result = __LINE__; 00528 } 00529 else 00530 { 00531 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00532 00533 if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN) 00534 { 00535 result = __LINE__; 00536 } 00537 else 00538 { 00539 tls_io_instance->on_send_complete = on_send_complete; 00540 tls_io_instance->on_send_complete_callback_context = callback_context; 00541 00542 int res = mbedtls_ssl_write(&tls_io_instance->ssl, buffer, size); 00543 if (res != size) 00544 { 00545 result = __LINE__; 00546 } 00547 else 00548 { 00549 result = 0; 00550 } 00551 } 00552 } 00553 00554 return result; 00555 } 00556 00557 void tlsio_mbedtls_dowork(CONCRETE_IO_HANDLE tls_io) 00558 { 00559 if (tls_io != NULL) 00560 { 00561 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00562 00563 if ((tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN) && 00564 (tls_io_instance->tlsio_state != TLSIO_STATE_ERROR)) 00565 { 00566 decode_ssl_received_bytes(tls_io_instance); 00567 xio_dowork(tls_io_instance->socket_io); 00568 } 00569 } 00570 } 00571 00572 const IO_INTERFACE_DESCRIPTION* tlsio_mbedtls_get_interface_description(void) 00573 { 00574 return &tlsio_mbedtls_interface_description; 00575 } 00576 00577 int tlsio_mbedtls_setoption(CONCRETE_IO_HANDLE tls_io, const char* optionName, const void* value) 00578 { 00579 int result = 0; 00580 00581 if (tls_io == NULL || optionName == NULL) 00582 { 00583 result = __LINE__; 00584 } 00585 else 00586 { 00587 TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io; 00588 00589 if (strcmp("TrustedCerts", optionName) == 0) 00590 { 00591 result = mbedtls_x509_crt_parse(&tls_io_instance->cacert,(const unsigned char *)value,(int)(strlen(value)+1)); 00592 if( result != 0 ) 00593 { 00594 result = __LINE__; 00595 } 00596 else 00597 { 00598 mbedtls_ssl_conf_ca_chain(&tls_io_instance->config,&tls_io_instance->cacert,NULL); 00599 } 00600 } 00601 else if (tls_io_instance->socket_io == NULL) 00602 { 00603 result = __LINE__; 00604 } 00605 else 00606 { 00607 result = xio_setoption(tls_io_instance->socket_io, optionName, value); 00608 } 00609 } 00610 00611 return result; 00612 } 00613 00614 #endif // USE_MBED_TLS
Generated on Tue Jul 12 2022 12:43:25 by
