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