quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ssl_server.c (10384B)


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