quickjs-tart

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

ssl_fork_server.c (11819B)


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