1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * SSL server demonstration program using pthread for handling multiple 3a8e1175bSopenharmony_ci * clients. 4a8e1175bSopenharmony_ci * 5a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 6a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 7a8e1175bSopenharmony_ci */ 8a8e1175bSopenharmony_ci 9a8e1175bSopenharmony_ci#include "mbedtls/build_info.h" 10a8e1175bSopenharmony_ci 11a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 12a8e1175bSopenharmony_ci 13a8e1175bSopenharmony_ci#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) || \ 14a8e1175bSopenharmony_ci !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) || \ 15a8e1175bSopenharmony_ci !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \ 16a8e1175bSopenharmony_ci !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ 17a8e1175bSopenharmony_ci !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_THREADING_C) || \ 18a8e1175bSopenharmony_ci !defined(MBEDTLS_THREADING_PTHREAD) || !defined(MBEDTLS_PEM_PARSE_C) 19a8e1175bSopenharmony_ciint main(void) 20a8e1175bSopenharmony_ci{ 21a8e1175bSopenharmony_ci mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C " 22a8e1175bSopenharmony_ci "and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or " 23a8e1175bSopenharmony_ci "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or " 24a8e1175bSopenharmony_ci "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or " 25a8e1175bSopenharmony_ci "MBEDTLS_THREADING_C and/or MBEDTLS_THREADING_PTHREAD " 26a8e1175bSopenharmony_ci "and/or MBEDTLS_PEM_PARSE_C not defined.\n"); 27a8e1175bSopenharmony_ci mbedtls_exit(0); 28a8e1175bSopenharmony_ci} 29a8e1175bSopenharmony_ci#else 30a8e1175bSopenharmony_ci 31a8e1175bSopenharmony_ci#include <stdlib.h> 32a8e1175bSopenharmony_ci#include <string.h> 33a8e1175bSopenharmony_ci 34a8e1175bSopenharmony_ci#if defined(_WIN32) 35a8e1175bSopenharmony_ci#include <windows.h> 36a8e1175bSopenharmony_ci#endif 37a8e1175bSopenharmony_ci 38a8e1175bSopenharmony_ci#include "mbedtls/entropy.h" 39a8e1175bSopenharmony_ci#include "mbedtls/ctr_drbg.h" 40a8e1175bSopenharmony_ci#include "mbedtls/x509.h" 41a8e1175bSopenharmony_ci#include "mbedtls/ssl.h" 42a8e1175bSopenharmony_ci#include "mbedtls/net_sockets.h" 43a8e1175bSopenharmony_ci#include "mbedtls/error.h" 44a8e1175bSopenharmony_ci#include "test/certs.h" 45a8e1175bSopenharmony_ci 46a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C) 47a8e1175bSopenharmony_ci#include "mbedtls/ssl_cache.h" 48a8e1175bSopenharmony_ci#endif 49a8e1175bSopenharmony_ci 50a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 51a8e1175bSopenharmony_ci#include "mbedtls/memory_buffer_alloc.h" 52a8e1175bSopenharmony_ci#endif 53a8e1175bSopenharmony_ci 54a8e1175bSopenharmony_ci 55a8e1175bSopenharmony_ci#define HTTP_RESPONSE \ 56a8e1175bSopenharmony_ci "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \ 57a8e1175bSopenharmony_ci "<h2>Mbed TLS Test Server</h2>\r\n" \ 58a8e1175bSopenharmony_ci "<p>Successful connection using: %s</p>\r\n" 59a8e1175bSopenharmony_ci 60a8e1175bSopenharmony_ci#define DEBUG_LEVEL 0 61a8e1175bSopenharmony_ci 62a8e1175bSopenharmony_ci#define MAX_NUM_THREADS 5 63a8e1175bSopenharmony_ci 64a8e1175bSopenharmony_cimbedtls_threading_mutex_t debug_mutex; 65a8e1175bSopenharmony_ci 66a8e1175bSopenharmony_cistatic void my_mutexed_debug(void *ctx, int level, 67a8e1175bSopenharmony_ci const char *file, int line, 68a8e1175bSopenharmony_ci const char *str) 69a8e1175bSopenharmony_ci{ 70a8e1175bSopenharmony_ci long int thread_id = (long int) pthread_self(); 71a8e1175bSopenharmony_ci 72a8e1175bSopenharmony_ci mbedtls_mutex_lock(&debug_mutex); 73a8e1175bSopenharmony_ci 74a8e1175bSopenharmony_ci ((void) level); 75a8e1175bSopenharmony_ci mbedtls_fprintf((FILE *) ctx, "%s:%04d: [ #%ld ] %s", 76a8e1175bSopenharmony_ci file, line, thread_id, str); 77a8e1175bSopenharmony_ci fflush((FILE *) ctx); 78a8e1175bSopenharmony_ci 79a8e1175bSopenharmony_ci mbedtls_mutex_unlock(&debug_mutex); 80a8e1175bSopenharmony_ci} 81a8e1175bSopenharmony_ci 82a8e1175bSopenharmony_citypedef struct { 83a8e1175bSopenharmony_ci mbedtls_net_context client_fd; 84a8e1175bSopenharmony_ci int thread_complete; 85a8e1175bSopenharmony_ci const mbedtls_ssl_config *config; 86a8e1175bSopenharmony_ci} thread_info_t; 87a8e1175bSopenharmony_ci 88a8e1175bSopenharmony_citypedef struct { 89a8e1175bSopenharmony_ci int active; 90a8e1175bSopenharmony_ci thread_info_t data; 91a8e1175bSopenharmony_ci pthread_t thread; 92a8e1175bSopenharmony_ci} pthread_info_t; 93a8e1175bSopenharmony_ci 94a8e1175bSopenharmony_cistatic thread_info_t base_info; 95a8e1175bSopenharmony_cistatic pthread_info_t threads[MAX_NUM_THREADS]; 96a8e1175bSopenharmony_ci 97a8e1175bSopenharmony_cistatic void *handle_ssl_connection(void *data) 98a8e1175bSopenharmony_ci{ 99a8e1175bSopenharmony_ci int ret, len; 100a8e1175bSopenharmony_ci thread_info_t *thread_info = (thread_info_t *) data; 101a8e1175bSopenharmony_ci mbedtls_net_context *client_fd = &thread_info->client_fd; 102a8e1175bSopenharmony_ci long int thread_id = (long int) pthread_self(); 103a8e1175bSopenharmony_ci unsigned char buf[1024]; 104a8e1175bSopenharmony_ci mbedtls_ssl_context ssl; 105a8e1175bSopenharmony_ci 106a8e1175bSopenharmony_ci /* Make sure memory references are valid */ 107a8e1175bSopenharmony_ci mbedtls_ssl_init(&ssl); 108a8e1175bSopenharmony_ci 109a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] Setting up SSL/TLS data\n", thread_id); 110a8e1175bSopenharmony_ci 111a8e1175bSopenharmony_ci /* 112a8e1175bSopenharmony_ci * 4. Get the SSL context ready 113a8e1175bSopenharmony_ci */ 114a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_setup(&ssl, thread_info->config)) != 0) { 115a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] failed: mbedtls_ssl_setup returned -0x%04x\n", 116a8e1175bSopenharmony_ci thread_id, (unsigned int) -ret); 117a8e1175bSopenharmony_ci goto thread_exit; 118a8e1175bSopenharmony_ci } 119a8e1175bSopenharmony_ci 120a8e1175bSopenharmony_ci mbedtls_ssl_set_bio(&ssl, client_fd, mbedtls_net_send, mbedtls_net_recv, NULL); 121a8e1175bSopenharmony_ci 122a8e1175bSopenharmony_ci /* 123a8e1175bSopenharmony_ci * 5. Handshake 124a8e1175bSopenharmony_ci */ 125a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] Performing the SSL/TLS handshake\n", thread_id); 126a8e1175bSopenharmony_ci 127a8e1175bSopenharmony_ci while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { 128a8e1175bSopenharmony_ci if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 129a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] failed: mbedtls_ssl_handshake returned -0x%04x\n", 130a8e1175bSopenharmony_ci thread_id, (unsigned int) -ret); 131a8e1175bSopenharmony_ci goto thread_exit; 132a8e1175bSopenharmony_ci } 133a8e1175bSopenharmony_ci } 134a8e1175bSopenharmony_ci 135a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] ok\n", thread_id); 136a8e1175bSopenharmony_ci 137a8e1175bSopenharmony_ci /* 138a8e1175bSopenharmony_ci * 6. Read the HTTP Request 139a8e1175bSopenharmony_ci */ 140a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] < Read from client\n", thread_id); 141a8e1175bSopenharmony_ci 142a8e1175bSopenharmony_ci do { 143a8e1175bSopenharmony_ci len = sizeof(buf) - 1; 144a8e1175bSopenharmony_ci memset(buf, 0, sizeof(buf)); 145a8e1175bSopenharmony_ci ret = mbedtls_ssl_read(&ssl, buf, len); 146a8e1175bSopenharmony_ci 147a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { 148a8e1175bSopenharmony_ci continue; 149a8e1175bSopenharmony_ci } 150a8e1175bSopenharmony_ci 151a8e1175bSopenharmony_ci if (ret <= 0) { 152a8e1175bSopenharmony_ci switch (ret) { 153a8e1175bSopenharmony_ci case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: 154a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] connection was closed gracefully\n", 155a8e1175bSopenharmony_ci thread_id); 156a8e1175bSopenharmony_ci goto thread_exit; 157a8e1175bSopenharmony_ci 158a8e1175bSopenharmony_ci case MBEDTLS_ERR_NET_CONN_RESET: 159a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] connection was reset by peer\n", 160a8e1175bSopenharmony_ci thread_id); 161a8e1175bSopenharmony_ci goto thread_exit; 162a8e1175bSopenharmony_ci 163a8e1175bSopenharmony_ci default: 164a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] mbedtls_ssl_read returned -0x%04x\n", 165a8e1175bSopenharmony_ci thread_id, (unsigned int) -ret); 166a8e1175bSopenharmony_ci goto thread_exit; 167a8e1175bSopenharmony_ci } 168a8e1175bSopenharmony_ci } 169a8e1175bSopenharmony_ci 170a8e1175bSopenharmony_ci len = ret; 171a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] %d bytes read\n=====\n%s\n=====\n", 172a8e1175bSopenharmony_ci thread_id, len, (char *) buf); 173a8e1175bSopenharmony_ci 174a8e1175bSopenharmony_ci if (ret > 0) { 175a8e1175bSopenharmony_ci break; 176a8e1175bSopenharmony_ci } 177a8e1175bSopenharmony_ci } while (1); 178a8e1175bSopenharmony_ci 179a8e1175bSopenharmony_ci /* 180a8e1175bSopenharmony_ci * 7. Write the 200 Response 181a8e1175bSopenharmony_ci */ 182a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] > Write to client:\n", thread_id); 183a8e1175bSopenharmony_ci 184a8e1175bSopenharmony_ci len = sprintf((char *) buf, HTTP_RESPONSE, 185a8e1175bSopenharmony_ci mbedtls_ssl_get_ciphersuite(&ssl)); 186a8e1175bSopenharmony_ci 187a8e1175bSopenharmony_ci while ((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0) { 188a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_NET_CONN_RESET) { 189a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] failed: peer closed the connection\n", 190a8e1175bSopenharmony_ci thread_id); 191a8e1175bSopenharmony_ci goto thread_exit; 192a8e1175bSopenharmony_ci } 193a8e1175bSopenharmony_ci 194a8e1175bSopenharmony_ci if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 195a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] failed: mbedtls_ssl_write returned -0x%04x\n", 196a8e1175bSopenharmony_ci thread_id, (unsigned int) ret); 197a8e1175bSopenharmony_ci goto thread_exit; 198a8e1175bSopenharmony_ci } 199a8e1175bSopenharmony_ci } 200a8e1175bSopenharmony_ci 201a8e1175bSopenharmony_ci len = ret; 202a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] %d bytes written\n=====\n%s\n=====\n", 203a8e1175bSopenharmony_ci thread_id, len, (char *) buf); 204a8e1175bSopenharmony_ci 205a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] . Closing the connection...", thread_id); 206a8e1175bSopenharmony_ci 207a8e1175bSopenharmony_ci while ((ret = mbedtls_ssl_close_notify(&ssl)) < 0) { 208a8e1175bSopenharmony_ci if (ret != MBEDTLS_ERR_SSL_WANT_READ && 209a8e1175bSopenharmony_ci ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 210a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] failed: mbedtls_ssl_close_notify returned -0x%04x\n", 211a8e1175bSopenharmony_ci thread_id, (unsigned int) ret); 212a8e1175bSopenharmony_ci goto thread_exit; 213a8e1175bSopenharmony_ci } 214a8e1175bSopenharmony_ci } 215a8e1175bSopenharmony_ci 216a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 217a8e1175bSopenharmony_ci 218a8e1175bSopenharmony_ci ret = 0; 219a8e1175bSopenharmony_ci 220a8e1175bSopenharmony_cithread_exit: 221a8e1175bSopenharmony_ci 222a8e1175bSopenharmony_ci#ifdef MBEDTLS_ERROR_C 223a8e1175bSopenharmony_ci if (ret != 0) { 224a8e1175bSopenharmony_ci char error_buf[100]; 225a8e1175bSopenharmony_ci mbedtls_strerror(ret, error_buf, 100); 226a8e1175bSopenharmony_ci mbedtls_printf(" [ #%ld ] Last error was: -0x%04x - %s\n\n", 227a8e1175bSopenharmony_ci thread_id, (unsigned int) -ret, error_buf); 228a8e1175bSopenharmony_ci } 229a8e1175bSopenharmony_ci#endif 230a8e1175bSopenharmony_ci 231a8e1175bSopenharmony_ci mbedtls_net_free(client_fd); 232a8e1175bSopenharmony_ci mbedtls_ssl_free(&ssl); 233a8e1175bSopenharmony_ci 234a8e1175bSopenharmony_ci thread_info->thread_complete = 1; 235a8e1175bSopenharmony_ci 236a8e1175bSopenharmony_ci return NULL; 237a8e1175bSopenharmony_ci} 238a8e1175bSopenharmony_ci 239a8e1175bSopenharmony_cistatic int thread_create(mbedtls_net_context *client_fd) 240a8e1175bSopenharmony_ci{ 241a8e1175bSopenharmony_ci int ret, i; 242a8e1175bSopenharmony_ci 243a8e1175bSopenharmony_ci /* 244a8e1175bSopenharmony_ci * Find in-active or finished thread slot 245a8e1175bSopenharmony_ci */ 246a8e1175bSopenharmony_ci for (i = 0; i < MAX_NUM_THREADS; i++) { 247a8e1175bSopenharmony_ci if (threads[i].active == 0) { 248a8e1175bSopenharmony_ci break; 249a8e1175bSopenharmony_ci } 250a8e1175bSopenharmony_ci 251a8e1175bSopenharmony_ci if (threads[i].data.thread_complete == 1) { 252a8e1175bSopenharmony_ci mbedtls_printf(" [ main ] Cleaning up thread %d\n", i); 253a8e1175bSopenharmony_ci pthread_join(threads[i].thread, NULL); 254a8e1175bSopenharmony_ci memset(&threads[i], 0, sizeof(pthread_info_t)); 255a8e1175bSopenharmony_ci break; 256a8e1175bSopenharmony_ci } 257a8e1175bSopenharmony_ci } 258a8e1175bSopenharmony_ci 259a8e1175bSopenharmony_ci if (i == MAX_NUM_THREADS) { 260a8e1175bSopenharmony_ci return -1; 261a8e1175bSopenharmony_ci } 262a8e1175bSopenharmony_ci 263a8e1175bSopenharmony_ci /* 264a8e1175bSopenharmony_ci * Fill thread-info for thread 265a8e1175bSopenharmony_ci */ 266a8e1175bSopenharmony_ci memcpy(&threads[i].data, &base_info, sizeof(base_info)); 267a8e1175bSopenharmony_ci threads[i].active = 1; 268a8e1175bSopenharmony_ci memcpy(&threads[i].data.client_fd, client_fd, sizeof(mbedtls_net_context)); 269a8e1175bSopenharmony_ci 270a8e1175bSopenharmony_ci if ((ret = pthread_create(&threads[i].thread, NULL, handle_ssl_connection, 271a8e1175bSopenharmony_ci &threads[i].data)) != 0) { 272a8e1175bSopenharmony_ci return ret; 273a8e1175bSopenharmony_ci } 274a8e1175bSopenharmony_ci 275a8e1175bSopenharmony_ci return 0; 276a8e1175bSopenharmony_ci} 277a8e1175bSopenharmony_ci 278a8e1175bSopenharmony_ciint main(void) 279a8e1175bSopenharmony_ci{ 280a8e1175bSopenharmony_ci int ret; 281a8e1175bSopenharmony_ci mbedtls_net_context listen_fd, client_fd; 282a8e1175bSopenharmony_ci const char pers[] = "ssl_pthread_server"; 283a8e1175bSopenharmony_ci 284a8e1175bSopenharmony_ci mbedtls_entropy_context entropy; 285a8e1175bSopenharmony_ci mbedtls_ctr_drbg_context ctr_drbg; 286a8e1175bSopenharmony_ci mbedtls_ssl_config conf; 287a8e1175bSopenharmony_ci mbedtls_x509_crt srvcert; 288a8e1175bSopenharmony_ci mbedtls_x509_crt cachain; 289a8e1175bSopenharmony_ci mbedtls_pk_context pkey; 290a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 291a8e1175bSopenharmony_ci unsigned char alloc_buf[100000]; 292a8e1175bSopenharmony_ci#endif 293a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C) 294a8e1175bSopenharmony_ci mbedtls_ssl_cache_context cache; 295a8e1175bSopenharmony_ci#endif 296a8e1175bSopenharmony_ci 297a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 298a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf)); 299a8e1175bSopenharmony_ci#endif 300a8e1175bSopenharmony_ci 301a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C) 302a8e1175bSopenharmony_ci mbedtls_ssl_cache_init(&cache); 303a8e1175bSopenharmony_ci#endif 304a8e1175bSopenharmony_ci 305a8e1175bSopenharmony_ci mbedtls_x509_crt_init(&srvcert); 306a8e1175bSopenharmony_ci mbedtls_x509_crt_init(&cachain); 307a8e1175bSopenharmony_ci 308a8e1175bSopenharmony_ci mbedtls_ssl_config_init(&conf); 309a8e1175bSopenharmony_ci mbedtls_ctr_drbg_init(&ctr_drbg); 310a8e1175bSopenharmony_ci memset(threads, 0, sizeof(threads)); 311a8e1175bSopenharmony_ci mbedtls_net_init(&listen_fd); 312a8e1175bSopenharmony_ci mbedtls_net_init(&client_fd); 313a8e1175bSopenharmony_ci 314a8e1175bSopenharmony_ci mbedtls_mutex_init(&debug_mutex); 315a8e1175bSopenharmony_ci 316a8e1175bSopenharmony_ci base_info.config = &conf; 317a8e1175bSopenharmony_ci 318a8e1175bSopenharmony_ci /* 319a8e1175bSopenharmony_ci * We use only a single entropy source that is used in all the threads. 320a8e1175bSopenharmony_ci */ 321a8e1175bSopenharmony_ci mbedtls_entropy_init(&entropy); 322a8e1175bSopenharmony_ci 323a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 324a8e1175bSopenharmony_ci psa_status_t status = psa_crypto_init(); 325a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 326a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n", 327a8e1175bSopenharmony_ci (int) status); 328a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; 329a8e1175bSopenharmony_ci goto exit; 330a8e1175bSopenharmony_ci } 331a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 332a8e1175bSopenharmony_ci 333a8e1175bSopenharmony_ci /* 334a8e1175bSopenharmony_ci * 1a. Seed the random number generator 335a8e1175bSopenharmony_ci */ 336a8e1175bSopenharmony_ci mbedtls_printf(" . Seeding the random number generator..."); 337a8e1175bSopenharmony_ci 338a8e1175bSopenharmony_ci if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, 339a8e1175bSopenharmony_ci (const unsigned char *) pers, 340a8e1175bSopenharmony_ci strlen(pers))) != 0) { 341a8e1175bSopenharmony_ci mbedtls_printf(" failed: mbedtls_ctr_drbg_seed returned -0x%04x\n", 342a8e1175bSopenharmony_ci (unsigned int) -ret); 343a8e1175bSopenharmony_ci goto exit; 344a8e1175bSopenharmony_ci } 345a8e1175bSopenharmony_ci 346a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 347a8e1175bSopenharmony_ci 348a8e1175bSopenharmony_ci /* 349a8e1175bSopenharmony_ci * 1b. Load the certificates and private RSA key 350a8e1175bSopenharmony_ci */ 351a8e1175bSopenharmony_ci mbedtls_printf("\n . Loading the server cert. and key..."); 352a8e1175bSopenharmony_ci fflush(stdout); 353a8e1175bSopenharmony_ci 354a8e1175bSopenharmony_ci /* 355a8e1175bSopenharmony_ci * This demonstration program uses embedded test certificates. 356a8e1175bSopenharmony_ci * Instead, you may want to use mbedtls_x509_crt_parse_file() to read the 357a8e1175bSopenharmony_ci * server and CA certificates, as well as mbedtls_pk_parse_keyfile(). 358a8e1175bSopenharmony_ci */ 359a8e1175bSopenharmony_ci ret = mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_srv_crt, 360a8e1175bSopenharmony_ci mbedtls_test_srv_crt_len); 361a8e1175bSopenharmony_ci if (ret != 0) { 362a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret); 363a8e1175bSopenharmony_ci goto exit; 364a8e1175bSopenharmony_ci } 365a8e1175bSopenharmony_ci 366a8e1175bSopenharmony_ci ret = mbedtls_x509_crt_parse(&cachain, (const unsigned char *) mbedtls_test_cas_pem, 367a8e1175bSopenharmony_ci mbedtls_test_cas_pem_len); 368a8e1175bSopenharmony_ci if (ret != 0) { 369a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret); 370a8e1175bSopenharmony_ci goto exit; 371a8e1175bSopenharmony_ci } 372a8e1175bSopenharmony_ci 373a8e1175bSopenharmony_ci mbedtls_pk_init(&pkey); 374a8e1175bSopenharmony_ci ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *) mbedtls_test_srv_key, 375a8e1175bSopenharmony_ci mbedtls_test_srv_key_len, NULL, 0, 376a8e1175bSopenharmony_ci mbedtls_ctr_drbg_random, &ctr_drbg); 377a8e1175bSopenharmony_ci if (ret != 0) { 378a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret); 379a8e1175bSopenharmony_ci goto exit; 380a8e1175bSopenharmony_ci } 381a8e1175bSopenharmony_ci 382a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 383a8e1175bSopenharmony_ci 384a8e1175bSopenharmony_ci /* 385a8e1175bSopenharmony_ci * 1c. Prepare SSL configuration 386a8e1175bSopenharmony_ci */ 387a8e1175bSopenharmony_ci mbedtls_printf(" . Setting up the SSL data...."); 388a8e1175bSopenharmony_ci 389a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_config_defaults(&conf, 390a8e1175bSopenharmony_ci MBEDTLS_SSL_IS_SERVER, 391a8e1175bSopenharmony_ci MBEDTLS_SSL_TRANSPORT_STREAM, 392a8e1175bSopenharmony_ci MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { 393a8e1175bSopenharmony_ci mbedtls_printf(" failed: mbedtls_ssl_config_defaults returned -0x%04x\n", 394a8e1175bSopenharmony_ci (unsigned int) -ret); 395a8e1175bSopenharmony_ci goto exit; 396a8e1175bSopenharmony_ci } 397a8e1175bSopenharmony_ci 398a8e1175bSopenharmony_ci mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); 399a8e1175bSopenharmony_ci mbedtls_ssl_conf_dbg(&conf, my_mutexed_debug, stdout); 400a8e1175bSopenharmony_ci 401a8e1175bSopenharmony_ci /* mbedtls_ssl_cache_get() and mbedtls_ssl_cache_set() are thread-safe if 402a8e1175bSopenharmony_ci * MBEDTLS_THREADING_C is set. 403a8e1175bSopenharmony_ci */ 404a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C) 405a8e1175bSopenharmony_ci mbedtls_ssl_conf_session_cache(&conf, &cache, 406a8e1175bSopenharmony_ci mbedtls_ssl_cache_get, 407a8e1175bSopenharmony_ci mbedtls_ssl_cache_set); 408a8e1175bSopenharmony_ci#endif 409a8e1175bSopenharmony_ci 410a8e1175bSopenharmony_ci mbedtls_ssl_conf_ca_chain(&conf, &cachain, NULL); 411a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey)) != 0) { 412a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret); 413a8e1175bSopenharmony_ci goto exit; 414a8e1175bSopenharmony_ci } 415a8e1175bSopenharmony_ci 416a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 417a8e1175bSopenharmony_ci 418a8e1175bSopenharmony_ci /* 419a8e1175bSopenharmony_ci * 2. Setup the listening TCP socket 420a8e1175bSopenharmony_ci */ 421a8e1175bSopenharmony_ci mbedtls_printf(" . Bind on https://localhost:4433/ ..."); 422a8e1175bSopenharmony_ci fflush(stdout); 423a8e1175bSopenharmony_ci 424a8e1175bSopenharmony_ci if ((ret = mbedtls_net_bind(&listen_fd, NULL, "4433", MBEDTLS_NET_PROTO_TCP)) != 0) { 425a8e1175bSopenharmony_ci mbedtls_printf(" failed\n ! mbedtls_net_bind returned %d\n\n", ret); 426a8e1175bSopenharmony_ci goto exit; 427a8e1175bSopenharmony_ci } 428a8e1175bSopenharmony_ci 429a8e1175bSopenharmony_ci mbedtls_printf(" ok\n"); 430a8e1175bSopenharmony_ci 431a8e1175bSopenharmony_cireset: 432a8e1175bSopenharmony_ci#ifdef MBEDTLS_ERROR_C 433a8e1175bSopenharmony_ci if (ret != 0) { 434a8e1175bSopenharmony_ci char error_buf[100]; 435a8e1175bSopenharmony_ci mbedtls_strerror(ret, error_buf, 100); 436a8e1175bSopenharmony_ci mbedtls_printf(" [ main ] Last error was: -0x%04x - %s\n", (unsigned int) -ret, 437a8e1175bSopenharmony_ci error_buf); 438a8e1175bSopenharmony_ci } 439a8e1175bSopenharmony_ci#endif 440a8e1175bSopenharmony_ci 441a8e1175bSopenharmony_ci /* 442a8e1175bSopenharmony_ci * 3. Wait until a client connects 443a8e1175bSopenharmony_ci */ 444a8e1175bSopenharmony_ci mbedtls_printf(" [ main ] Waiting for a remote connection\n"); 445a8e1175bSopenharmony_ci 446a8e1175bSopenharmony_ci if ((ret = mbedtls_net_accept(&listen_fd, &client_fd, 447a8e1175bSopenharmony_ci NULL, 0, NULL)) != 0) { 448a8e1175bSopenharmony_ci mbedtls_printf(" [ main ] failed: mbedtls_net_accept returned -0x%04x\n", 449a8e1175bSopenharmony_ci (unsigned int) ret); 450a8e1175bSopenharmony_ci goto exit; 451a8e1175bSopenharmony_ci } 452a8e1175bSopenharmony_ci 453a8e1175bSopenharmony_ci mbedtls_printf(" [ main ] ok\n"); 454a8e1175bSopenharmony_ci mbedtls_printf(" [ main ] Creating a new thread\n"); 455a8e1175bSopenharmony_ci 456a8e1175bSopenharmony_ci if ((ret = thread_create(&client_fd)) != 0) { 457a8e1175bSopenharmony_ci mbedtls_printf(" [ main ] failed: thread_create returned %d\n", ret); 458a8e1175bSopenharmony_ci mbedtls_net_free(&client_fd); 459a8e1175bSopenharmony_ci goto reset; 460a8e1175bSopenharmony_ci } 461a8e1175bSopenharmony_ci 462a8e1175bSopenharmony_ci ret = 0; 463a8e1175bSopenharmony_ci goto reset; 464a8e1175bSopenharmony_ci 465a8e1175bSopenharmony_ciexit: 466a8e1175bSopenharmony_ci mbedtls_x509_crt_free(&srvcert); 467a8e1175bSopenharmony_ci mbedtls_pk_free(&pkey); 468a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C) 469a8e1175bSopenharmony_ci mbedtls_ssl_cache_free(&cache); 470a8e1175bSopenharmony_ci#endif 471a8e1175bSopenharmony_ci mbedtls_ctr_drbg_free(&ctr_drbg); 472a8e1175bSopenharmony_ci mbedtls_entropy_free(&entropy); 473a8e1175bSopenharmony_ci mbedtls_ssl_config_free(&conf); 474a8e1175bSopenharmony_ci mbedtls_net_free(&listen_fd); 475a8e1175bSopenharmony_ci mbedtls_mutex_free(&debug_mutex); 476a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 477a8e1175bSopenharmony_ci mbedtls_memory_buffer_alloc_free(); 478a8e1175bSopenharmony_ci#endif 479a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 480a8e1175bSopenharmony_ci mbedtls_psa_crypto_free(); 481a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 482a8e1175bSopenharmony_ci 483a8e1175bSopenharmony_ci mbedtls_exit(ret); 484a8e1175bSopenharmony_ci} 485a8e1175bSopenharmony_ci 486a8e1175bSopenharmony_ci#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && 487a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C && 488a8e1175bSopenharmony_ci MBEDTLS_RSA_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_THREADING_C && 489a8e1175bSopenharmony_ci MBEDTLS_THREADING_PTHREAD && MBEDTLS_PEM_PARSE_C */ 490