1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * SSL server demonstration program using fork() for handling multiple clients 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci#include "mbedtls/build_info.h" 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 11a8e1175bSopenharmony_ci 12a8e1175bSopenharmony_ci#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) || \ 13a8e1175bSopenharmony_ci !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) || \ 14a8e1175bSopenharmony_ci !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \ 15a8e1175bSopenharmony_ci !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ 16a8e1175bSopenharmony_ci !defined(MBEDTLS_TIMING_C) || !defined(MBEDTLS_FS_IO) || \ 17a8e1175bSopenharmony_ci !defined(MBEDTLS_PEM_PARSE_C) 18a8e1175bSopenharmony_ciint main(int argc, char *argv[]) 19a8e1175bSopenharmony_ci{ 20a8e1175bSopenharmony_ci ((void) argc); 21a8e1175bSopenharmony_ci ((void) argv); 22a8e1175bSopenharmony_ci 23a8e1175bSopenharmony_ci mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C " 24a8e1175bSopenharmony_ci "and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or " 25a8e1175bSopenharmony_ci "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or " 26a8e1175bSopenharmony_ci "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or " 27a8e1175bSopenharmony_ci "MBEDTLS_TIMING_C and/or MBEDTLS_PEM_PARSE_C not defined.\n"); 28a8e1175bSopenharmony_ci mbedtls_exit(0); 29a8e1175bSopenharmony_ci} 30a8e1175bSopenharmony_ci#elif defined(_WIN32) 31a8e1175bSopenharmony_ciint main(void) 32a8e1175bSopenharmony_ci{ 33a8e1175bSopenharmony_ci mbedtls_printf("_WIN32 defined. This application requires fork() and signals " 34a8e1175bSopenharmony_ci "to work correctly.\n"); 35a8e1175bSopenharmony_ci mbedtls_exit(0); 36a8e1175bSopenharmony_ci} 37a8e1175bSopenharmony_ci#else 38a8e1175bSopenharmony_ci 39a8e1175bSopenharmony_ci#include "mbedtls/entropy.h" 40a8e1175bSopenharmony_ci#include "mbedtls/ctr_drbg.h" 41a8e1175bSopenharmony_ci#include "test/certs.h" 42a8e1175bSopenharmony_ci#include "mbedtls/x509.h" 43a8e1175bSopenharmony_ci#include "mbedtls/ssl.h" 44a8e1175bSopenharmony_ci#include "mbedtls/net_sockets.h" 45a8e1175bSopenharmony_ci#include "mbedtls/timing.h" 46a8e1175bSopenharmony_ci 47a8e1175bSopenharmony_ci#include <string.h> 48a8e1175bSopenharmony_ci#include <signal.h> 49a8e1175bSopenharmony_ci 50a8e1175bSopenharmony_ci#if !defined(_MSC_VER) || defined(EFIX64) || defined(EFI32) 51a8e1175bSopenharmony_ci#include <unistd.h> 52a8e1175bSopenharmony_ci#endif 53a8e1175bSopenharmony_ci 54a8e1175bSopenharmony_ci#define HTTP_RESPONSE \ 55a8e1175bSopenharmony_ci "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \ 56a8e1175bSopenharmony_ci "<h2>Mbed TLS Test Server</h2>\r\n" \ 57a8e1175bSopenharmony_ci "<p>Successful connection using: %s</p>\r\n" 58a8e1175bSopenharmony_ci 59a8e1175bSopenharmony_ci#define DEBUG_LEVEL 0 60a8e1175bSopenharmony_ci 61a8e1175bSopenharmony_ci 62a8e1175bSopenharmony_cistatic void my_debug(void *ctx, int level, 63a8e1175bSopenharmony_ci const char *file, int line, 64a8e1175bSopenharmony_ci const char *str) 65a8e1175bSopenharmony_ci{ 66a8e1175bSopenharmony_ci ((void) level); 67a8e1175bSopenharmony_ci 68a8e1175bSopenharmony_ci mbedtls_fprintf((FILE *) ctx, "%s:%04d: %s", file, line, str); 69a8e1175bSopenharmony_ci fflush((FILE *) ctx); 70a8e1175bSopenharmony_ci} 71a8e1175bSopenharmony_ci 72a8e1175bSopenharmony_ciint main(void) 73a8e1175bSopenharmony_ci{ 74a8e1175bSopenharmony_ci int ret = 1, len, cnt = 0, pid; 75a8e1175bSopenharmony_ci int exit_code = MBEDTLS_EXIT_FAILURE; 76a8e1175bSopenharmony_ci mbedtls_net_context listen_fd, client_fd; 77a8e1175bSopenharmony_ci unsigned char buf[1024]; 78a8e1175bSopenharmony_ci const char *pers = "ssl_fork_server"; 79a8e1175bSopenharmony_ci 80a8e1175bSopenharmony_ci mbedtls_entropy_context entropy; 81a8e1175bSopenharmony_ci mbedtls_ctr_drbg_context ctr_drbg; 82a8e1175bSopenharmony_ci mbedtls_ssl_context ssl; 83a8e1175bSopenharmony_ci mbedtls_ssl_config conf; 84a8e1175bSopenharmony_ci mbedtls_x509_crt srvcert; 85a8e1175bSopenharmony_ci mbedtls_pk_context pkey; 86a8e1175bSopenharmony_ci 87a8e1175bSopenharmony_ci mbedtls_net_init(&listen_fd); 88a8e1175bSopenharmony_ci mbedtls_net_init(&client_fd); 89a8e1175bSopenharmony_ci mbedtls_ssl_init(&ssl); 90a8e1175bSopenharmony_ci mbedtls_ssl_config_init(&conf); 91a8e1175bSopenharmony_ci mbedtls_entropy_init(&entropy); 92a8e1175bSopenharmony_ci mbedtls_pk_init(&pkey); 93a8e1175bSopenharmony_ci mbedtls_x509_crt_init(&srvcert); 94a8e1175bSopenharmony_ci mbedtls_ctr_drbg_init(&ctr_drbg); 95a8e1175bSopenharmony_ci 96a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 97a8e1175bSopenharmony_ci psa_status_t status = psa_crypto_init(); 98a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 99a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n", 100a8e1175bSopenharmony_ci (int) status); 101a8e1175bSopenharmony_ci goto exit; 102a8e1175bSopenharmony_ci } 103a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 104a8e1175bSopenharmony_ci 105a8e1175bSopenharmony_ci signal(SIGCHLD, SIG_IGN); 106a8e1175bSopenharmony_ci 107a8e1175bSopenharmony_ci /* 108a8e1175bSopenharmony_ci * 0. Initial seeding of the RNG 109a8e1175bSopenharmony_ci */ 110a8e1175bSopenharmony_ci mbedtls_printf("\n . Initial seeding of the random generator..."); 111a8e1175bSopenharmony_ci fflush(stdout); 112a8e1175bSopenharmony_ci 113a8e1175bSopenharmony_ci if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, 114a8e1175bSopenharmony_ci (const unsigned char *) pers, 115a8e1175bSopenharmony_ci strlen(pers))) != 0) { 116a8e1175bSopenharmony_ci mbedtls_printf(" failed! mbedtls_ctr_drbg_seed returned %d\n\n", ret); 117a8e1175bSopenharmony_ci goto exit; 118a8e1175bSopenharmony_ci } 119a8e1175bSopenharmony_ci 120a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 121a8e1175bSopenharmony_ci 122a8e1175bSopenharmony_ci /* 123a8e1175bSopenharmony_ci * 1. Load the certificates and private RSA key 124a8e1175bSopenharmony_ci */ 125a8e1175bSopenharmony_ci mbedtls_printf(" . Loading the server cert. and key..."); 126a8e1175bSopenharmony_ci fflush(stdout); 127a8e1175bSopenharmony_ci 128a8e1175bSopenharmony_ci /* 129a8e1175bSopenharmony_ci * This demonstration program uses embedded test certificates. 130a8e1175bSopenharmony_ci * Instead, you may want to use mbedtls_x509_crt_parse_file() to read the 131a8e1175bSopenharmony_ci * server and CA certificates, as well as mbedtls_pk_parse_keyfile(). 132a8e1175bSopenharmony_ci */ 133a8e1175bSopenharmony_ci ret = mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_srv_crt, 134a8e1175bSopenharmony_ci mbedtls_test_srv_crt_len); 135a8e1175bSopenharmony_ci if (ret != 0) { 136a8e1175bSopenharmony_ci mbedtls_printf(" failed! mbedtls_x509_crt_parse returned %d\n\n", ret); 137a8e1175bSopenharmony_ci goto exit; 138a8e1175bSopenharmony_ci } 139a8e1175bSopenharmony_ci 140a8e1175bSopenharmony_ci ret = mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_cas_pem, 141a8e1175bSopenharmony_ci mbedtls_test_cas_pem_len); 142a8e1175bSopenharmony_ci if (ret != 0) { 143a8e1175bSopenharmony_ci mbedtls_printf(" failed! mbedtls_x509_crt_parse returned %d\n\n", ret); 144a8e1175bSopenharmony_ci goto exit; 145a8e1175bSopenharmony_ci } 146a8e1175bSopenharmony_ci 147a8e1175bSopenharmony_ci ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *) mbedtls_test_srv_key, 148a8e1175bSopenharmony_ci mbedtls_test_srv_key_len, NULL, 0, 149a8e1175bSopenharmony_ci mbedtls_ctr_drbg_random, &ctr_drbg); 150a8e1175bSopenharmony_ci if (ret != 0) { 151a8e1175bSopenharmony_ci mbedtls_printf(" failed! mbedtls_pk_parse_key returned %d\n\n", ret); 152a8e1175bSopenharmony_ci goto exit; 153a8e1175bSopenharmony_ci } 154a8e1175bSopenharmony_ci 155a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 156a8e1175bSopenharmony_ci 157a8e1175bSopenharmony_ci /* 158a8e1175bSopenharmony_ci * 1b. Prepare SSL configuration 159a8e1175bSopenharmony_ci */ 160a8e1175bSopenharmony_ci mbedtls_printf(" . Configuring SSL..."); 161a8e1175bSopenharmony_ci fflush(stdout); 162a8e1175bSopenharmony_ci 163a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_config_defaults(&conf, 164a8e1175bSopenharmony_ci MBEDTLS_SSL_IS_SERVER, 165a8e1175bSopenharmony_ci MBEDTLS_SSL_TRANSPORT_STREAM, 166a8e1175bSopenharmony_ci MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { 167a8e1175bSopenharmony_ci mbedtls_printf(" failed! mbedtls_ssl_config_defaults returned %d\n\n", ret); 168a8e1175bSopenharmony_ci goto exit; 169a8e1175bSopenharmony_ci } 170a8e1175bSopenharmony_ci 171a8e1175bSopenharmony_ci mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); 172a8e1175bSopenharmony_ci mbedtls_ssl_conf_dbg(&conf, my_debug, stdout); 173a8e1175bSopenharmony_ci 174a8e1175bSopenharmony_ci mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL); 175a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey)) != 0) { 176a8e1175bSopenharmony_ci mbedtls_printf(" failed! mbedtls_ssl_conf_own_cert returned %d\n\n", ret); 177a8e1175bSopenharmony_ci goto exit; 178a8e1175bSopenharmony_ci } 179a8e1175bSopenharmony_ci 180a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 181a8e1175bSopenharmony_ci 182a8e1175bSopenharmony_ci /* 183a8e1175bSopenharmony_ci * 2. Setup the listening TCP socket 184a8e1175bSopenharmony_ci */ 185a8e1175bSopenharmony_ci mbedtls_printf(" . Bind on https://localhost:4433/ ..."); 186a8e1175bSopenharmony_ci fflush(stdout); 187a8e1175bSopenharmony_ci 188a8e1175bSopenharmony_ci if ((ret = mbedtls_net_bind(&listen_fd, NULL, "4433", MBEDTLS_NET_PROTO_TCP)) != 0) { 189a8e1175bSopenharmony_ci mbedtls_printf(" failed! mbedtls_net_bind returned %d\n\n", ret); 190a8e1175bSopenharmony_ci goto exit; 191a8e1175bSopenharmony_ci } 192a8e1175bSopenharmony_ci 193a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 194a8e1175bSopenharmony_ci 195a8e1175bSopenharmony_ci while (1) { 196a8e1175bSopenharmony_ci /* 197a8e1175bSopenharmony_ci * 3. Wait until a client connects 198a8e1175bSopenharmony_ci */ 199a8e1175bSopenharmony_ci mbedtls_net_init(&client_fd); 200a8e1175bSopenharmony_ci mbedtls_ssl_init(&ssl); 201a8e1175bSopenharmony_ci 202a8e1175bSopenharmony_ci mbedtls_printf(" . Waiting for a remote connection ...\n"); 203a8e1175bSopenharmony_ci fflush(stdout); 204a8e1175bSopenharmony_ci 205a8e1175bSopenharmony_ci if ((ret = mbedtls_net_accept(&listen_fd, &client_fd, 206a8e1175bSopenharmony_ci NULL, 0, NULL)) != 0) { 207a8e1175bSopenharmony_ci mbedtls_printf(" failed! mbedtls_net_accept returned %d\n\n", ret); 208a8e1175bSopenharmony_ci goto exit; 209a8e1175bSopenharmony_ci } 210a8e1175bSopenharmony_ci 211a8e1175bSopenharmony_ci /* 212a8e1175bSopenharmony_ci * 3.5. Forking server thread 213a8e1175bSopenharmony_ci */ 214a8e1175bSopenharmony_ci 215a8e1175bSopenharmony_ci mbedtls_printf(" . Forking to handle connection ..."); 216a8e1175bSopenharmony_ci fflush(stdout); 217a8e1175bSopenharmony_ci 218a8e1175bSopenharmony_ci pid = fork(); 219a8e1175bSopenharmony_ci 220a8e1175bSopenharmony_ci if (pid < 0) { 221a8e1175bSopenharmony_ci mbedtls_printf(" failed! fork returned %d\n\n", pid); 222a8e1175bSopenharmony_ci goto exit; 223a8e1175bSopenharmony_ci } 224a8e1175bSopenharmony_ci 225a8e1175bSopenharmony_ci if (pid != 0) { 226a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 227a8e1175bSopenharmony_ci mbedtls_net_close(&client_fd); 228a8e1175bSopenharmony_ci 229a8e1175bSopenharmony_ci if ((ret = mbedtls_ctr_drbg_reseed(&ctr_drbg, 230a8e1175bSopenharmony_ci (const unsigned char *) "parent", 231a8e1175bSopenharmony_ci 6)) != 0) { 232a8e1175bSopenharmony_ci mbedtls_printf(" failed! mbedtls_ctr_drbg_reseed returned %d\n\n", ret); 233a8e1175bSopenharmony_ci goto exit; 234a8e1175bSopenharmony_ci } 235a8e1175bSopenharmony_ci 236a8e1175bSopenharmony_ci continue; 237a8e1175bSopenharmony_ci } 238a8e1175bSopenharmony_ci 239a8e1175bSopenharmony_ci mbedtls_net_close(&listen_fd); 240a8e1175bSopenharmony_ci 241a8e1175bSopenharmony_ci pid = getpid(); 242a8e1175bSopenharmony_ci 243a8e1175bSopenharmony_ci /* 244a8e1175bSopenharmony_ci * 4. Setup stuff 245a8e1175bSopenharmony_ci */ 246a8e1175bSopenharmony_ci mbedtls_printf("pid %d: Setting up the SSL data.\n", pid); 247a8e1175bSopenharmony_ci fflush(stdout); 248a8e1175bSopenharmony_ci 249a8e1175bSopenharmony_ci if ((ret = mbedtls_ctr_drbg_reseed(&ctr_drbg, 250a8e1175bSopenharmony_ci (const unsigned char *) "child", 251a8e1175bSopenharmony_ci 5)) != 0) { 252a8e1175bSopenharmony_ci mbedtls_printf( 253a8e1175bSopenharmony_ci "pid %d: SSL setup failed! mbedtls_ctr_drbg_reseed returned %d\n\n", 254a8e1175bSopenharmony_ci pid, ret); 255a8e1175bSopenharmony_ci goto exit; 256a8e1175bSopenharmony_ci } 257a8e1175bSopenharmony_ci 258a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) { 259a8e1175bSopenharmony_ci mbedtls_printf( 260a8e1175bSopenharmony_ci "pid %d: SSL setup failed! mbedtls_ssl_setup returned %d\n\n", 261a8e1175bSopenharmony_ci pid, ret); 262a8e1175bSopenharmony_ci goto exit; 263a8e1175bSopenharmony_ci } 264a8e1175bSopenharmony_ci 265a8e1175bSopenharmony_ci mbedtls_ssl_set_bio(&ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL); 266a8e1175bSopenharmony_ci 267a8e1175bSopenharmony_ci mbedtls_printf("pid %d: SSL setup ok\n", pid); 268a8e1175bSopenharmony_ci 269a8e1175bSopenharmony_ci /* 270a8e1175bSopenharmony_ci * 5. Handshake 271a8e1175bSopenharmony_ci */ 272a8e1175bSopenharmony_ci mbedtls_printf("pid %d: Performing the SSL/TLS handshake.\n", pid); 273a8e1175bSopenharmony_ci fflush(stdout); 274a8e1175bSopenharmony_ci 275a8e1175bSopenharmony_ci while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { 276a8e1175bSopenharmony_ci if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 277a8e1175bSopenharmony_ci mbedtls_printf( 278a8e1175bSopenharmony_ci "pid %d: SSL handshake failed! mbedtls_ssl_handshake returned %d\n\n", 279a8e1175bSopenharmony_ci pid, ret); 280a8e1175bSopenharmony_ci goto exit; 281a8e1175bSopenharmony_ci } 282a8e1175bSopenharmony_ci } 283a8e1175bSopenharmony_ci 284a8e1175bSopenharmony_ci mbedtls_printf("pid %d: SSL handshake ok\n", pid); 285a8e1175bSopenharmony_ci 286a8e1175bSopenharmony_ci /* 287a8e1175bSopenharmony_ci * 6. Read the HTTP Request 288a8e1175bSopenharmony_ci */ 289a8e1175bSopenharmony_ci mbedtls_printf("pid %d: Start reading from client.\n", pid); 290a8e1175bSopenharmony_ci fflush(stdout); 291a8e1175bSopenharmony_ci 292a8e1175bSopenharmony_ci do { 293a8e1175bSopenharmony_ci len = sizeof(buf) - 1; 294a8e1175bSopenharmony_ci memset(buf, 0, sizeof(buf)); 295a8e1175bSopenharmony_ci ret = mbedtls_ssl_read(&ssl, buf, len); 296a8e1175bSopenharmony_ci 297a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { 298a8e1175bSopenharmony_ci continue; 299a8e1175bSopenharmony_ci } 300a8e1175bSopenharmony_ci 301a8e1175bSopenharmony_ci if (ret <= 0) { 302a8e1175bSopenharmony_ci switch (ret) { 303a8e1175bSopenharmony_ci case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: 304a8e1175bSopenharmony_ci mbedtls_printf("pid %d: connection was closed gracefully\n", pid); 305a8e1175bSopenharmony_ci break; 306a8e1175bSopenharmony_ci 307a8e1175bSopenharmony_ci case MBEDTLS_ERR_NET_CONN_RESET: 308a8e1175bSopenharmony_ci mbedtls_printf("pid %d: connection was reset by peer\n", pid); 309a8e1175bSopenharmony_ci break; 310a8e1175bSopenharmony_ci 311a8e1175bSopenharmony_ci default: 312a8e1175bSopenharmony_ci mbedtls_printf("pid %d: mbedtls_ssl_read returned %d\n", pid, ret); 313a8e1175bSopenharmony_ci break; 314a8e1175bSopenharmony_ci } 315a8e1175bSopenharmony_ci 316a8e1175bSopenharmony_ci break; 317a8e1175bSopenharmony_ci } 318a8e1175bSopenharmony_ci 319a8e1175bSopenharmony_ci len = ret; 320a8e1175bSopenharmony_ci mbedtls_printf("pid %d: %d bytes read\n\n%s", pid, len, (char *) buf); 321a8e1175bSopenharmony_ci 322a8e1175bSopenharmony_ci if (ret > 0) { 323a8e1175bSopenharmony_ci break; 324a8e1175bSopenharmony_ci } 325a8e1175bSopenharmony_ci } while (1); 326a8e1175bSopenharmony_ci 327a8e1175bSopenharmony_ci /* 328a8e1175bSopenharmony_ci * 7. Write the 200 Response 329a8e1175bSopenharmony_ci */ 330a8e1175bSopenharmony_ci mbedtls_printf("pid %d: Start writing to client.\n", pid); 331a8e1175bSopenharmony_ci fflush(stdout); 332a8e1175bSopenharmony_ci 333a8e1175bSopenharmony_ci len = sprintf((char *) buf, HTTP_RESPONSE, 334a8e1175bSopenharmony_ci mbedtls_ssl_get_ciphersuite(&ssl)); 335a8e1175bSopenharmony_ci 336a8e1175bSopenharmony_ci while (cnt++ < 100) { 337a8e1175bSopenharmony_ci while ((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0) { 338a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_NET_CONN_RESET) { 339a8e1175bSopenharmony_ci mbedtls_printf( 340a8e1175bSopenharmony_ci "pid %d: Write failed! peer closed the connection\n\n", pid); 341a8e1175bSopenharmony_ci goto exit; 342a8e1175bSopenharmony_ci } 343a8e1175bSopenharmony_ci 344a8e1175bSopenharmony_ci if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 345a8e1175bSopenharmony_ci mbedtls_printf( 346a8e1175bSopenharmony_ci "pid %d: Write failed! mbedtls_ssl_write returned %d\n\n", 347a8e1175bSopenharmony_ci pid, ret); 348a8e1175bSopenharmony_ci goto exit; 349a8e1175bSopenharmony_ci } 350a8e1175bSopenharmony_ci } 351a8e1175bSopenharmony_ci len = ret; 352a8e1175bSopenharmony_ci mbedtls_printf("pid %d: %d bytes written\n\n%s\n", pid, len, (char *) buf); 353a8e1175bSopenharmony_ci 354a8e1175bSopenharmony_ci mbedtls_net_usleep(1000000); 355a8e1175bSopenharmony_ci } 356a8e1175bSopenharmony_ci 357a8e1175bSopenharmony_ci mbedtls_ssl_close_notify(&ssl); 358a8e1175bSopenharmony_ci goto exit; 359a8e1175bSopenharmony_ci } 360a8e1175bSopenharmony_ci 361a8e1175bSopenharmony_ci exit_code = MBEDTLS_EXIT_SUCCESS; 362a8e1175bSopenharmony_ci 363a8e1175bSopenharmony_ciexit: 364a8e1175bSopenharmony_ci mbedtls_net_free(&client_fd); 365a8e1175bSopenharmony_ci mbedtls_net_free(&listen_fd); 366a8e1175bSopenharmony_ci mbedtls_x509_crt_free(&srvcert); 367a8e1175bSopenharmony_ci mbedtls_pk_free(&pkey); 368a8e1175bSopenharmony_ci mbedtls_ssl_free(&ssl); 369a8e1175bSopenharmony_ci mbedtls_ssl_config_free(&conf); 370a8e1175bSopenharmony_ci mbedtls_ctr_drbg_free(&ctr_drbg); 371a8e1175bSopenharmony_ci mbedtls_entropy_free(&entropy); 372a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 373a8e1175bSopenharmony_ci mbedtls_psa_crypto_free(); 374a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 375a8e1175bSopenharmony_ci 376a8e1175bSopenharmony_ci mbedtls_exit(exit_code); 377a8e1175bSopenharmony_ci} 378a8e1175bSopenharmony_ci#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && 379a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C && 380a8e1175bSopenharmony_ci MBEDTLS_RSA_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_PEM_PARSE_C && 381a8e1175bSopenharmony_ci ! _WIN32 */ 382