quickjs-tart

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

ssl_client1.c (8384B)


      1 /*
      2  *  SSL client 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_CLI_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_CLI_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 "mbedtls/net_sockets.h"
     26 #include "mbedtls/debug.h"
     27 #include "mbedtls/ssl.h"
     28 #include "mbedtls/entropy.h"
     29 #include "mbedtls/ctr_drbg.h"
     30 #include "mbedtls/error.h"
     31 #include "test/certs.h"
     32 
     33 #include <string.h>
     34 
     35 #define SERVER_PORT "4433"
     36 #define SERVER_NAME "localhost"
     37 #define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
     38 
     39 #define DEBUG_LEVEL 1
     40 
     41 
     42 static void my_debug(void *ctx, int level,
     43                      const char *file, int line,
     44                      const char *str)
     45 {
     46     ((void) level);
     47 
     48     mbedtls_fprintf((FILE *) ctx, "%s:%04d: %s", file, line, str);
     49     fflush((FILE *) ctx);
     50 }
     51 
     52 int main(void)
     53 {
     54     int ret = 1, len;
     55     int exit_code = MBEDTLS_EXIT_FAILURE;
     56     mbedtls_net_context server_fd;
     57     uint32_t flags;
     58     unsigned char buf[1024];
     59     const char *pers = "ssl_client1";
     60 
     61     mbedtls_entropy_context entropy;
     62     mbedtls_ctr_drbg_context ctr_drbg;
     63     mbedtls_ssl_context ssl;
     64     mbedtls_ssl_config conf;
     65     mbedtls_x509_crt cacert;
     66 
     67 #if defined(MBEDTLS_DEBUG_C)
     68     mbedtls_debug_set_threshold(DEBUG_LEVEL);
     69 #endif
     70 
     71     /*
     72      * 0. Initialize the RNG and the session data
     73      */
     74     mbedtls_net_init(&server_fd);
     75     mbedtls_ssl_init(&ssl);
     76     mbedtls_ssl_config_init(&conf);
     77     mbedtls_x509_crt_init(&cacert);
     78     mbedtls_ctr_drbg_init(&ctr_drbg);
     79     mbedtls_entropy_init(&entropy);
     80 
     81 #if defined(MBEDTLS_USE_PSA_CRYPTO)
     82     psa_status_t status = psa_crypto_init();
     83     if (status != PSA_SUCCESS) {
     84         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
     85                         (int) status);
     86         goto exit;
     87     }
     88 #endif /* MBEDTLS_USE_PSA_CRYPTO */
     89 
     90     mbedtls_printf("\n  . Seeding the random number generator...");
     91     fflush(stdout);
     92 
     93 
     94     if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
     95                                      (const unsigned char *) pers,
     96                                      strlen(pers))) != 0) {
     97         mbedtls_printf(" failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret);
     98         goto exit;
     99     }
    100 
    101     mbedtls_printf(" ok\n");
    102 
    103     /*
    104      * 0. Initialize certificates
    105      */
    106     mbedtls_printf("  . Loading the CA root certificate ...");
    107     fflush(stdout);
    108 
    109     ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *) mbedtls_test_cas_pem,
    110                                  mbedtls_test_cas_pem_len);
    111     if (ret < 0) {
    112         mbedtls_printf(" failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n",
    113                        (unsigned int) -ret);
    114         goto exit;
    115     }
    116 
    117     mbedtls_printf(" ok (%d skipped)\n", ret);
    118 
    119     /*
    120      * 1. Start the connection
    121      */
    122     mbedtls_printf("  . Connecting to tcp/%s/%s...", SERVER_NAME, SERVER_PORT);
    123     fflush(stdout);
    124 
    125     if ((ret = mbedtls_net_connect(&server_fd, SERVER_NAME,
    126                                    SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) {
    127         mbedtls_printf(" failed\n  ! mbedtls_net_connect returned %d\n\n", ret);
    128         goto exit;
    129     }
    130 
    131     mbedtls_printf(" ok\n");
    132 
    133     /*
    134      * 2. Setup stuff
    135      */
    136     mbedtls_printf("  . Setting up the SSL/TLS structure...");
    137     fflush(stdout);
    138 
    139     if ((ret = mbedtls_ssl_config_defaults(&conf,
    140                                            MBEDTLS_SSL_IS_CLIENT,
    141                                            MBEDTLS_SSL_TRANSPORT_STREAM,
    142                                            MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
    143         mbedtls_printf(" failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret);
    144         goto exit;
    145     }
    146 
    147     mbedtls_printf(" ok\n");
    148 
    149     /* OPTIONAL is not optimal for security,
    150      * but makes interop easier in this simplified example */
    151     mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
    152     mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
    153     mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
    154     mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
    155 
    156     if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
    157         mbedtls_printf(" failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret);
    158         goto exit;
    159     }
    160 
    161     if ((ret = mbedtls_ssl_set_hostname(&ssl, SERVER_NAME)) != 0) {
    162         mbedtls_printf(" failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret);
    163         goto exit;
    164     }
    165 
    166     mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
    167 
    168     /*
    169      * 4. Handshake
    170      */
    171     mbedtls_printf("  . Performing the SSL/TLS handshake...");
    172     fflush(stdout);
    173 
    174     while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
    175         if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
    176             mbedtls_printf(" failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n",
    177                            (unsigned int) -ret);
    178             goto exit;
    179         }
    180     }
    181 
    182     mbedtls_printf(" ok\n");
    183 
    184     /*
    185      * 5. Verify the server certificate
    186      */
    187     mbedtls_printf("  . Verifying peer X.509 certificate...");
    188 
    189     /* In real life, we probably want to bail out when ret != 0 */
    190     if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) {
    191 #if !defined(MBEDTLS_X509_REMOVE_INFO)
    192         char vrfy_buf[512];
    193 #endif
    194 
    195         mbedtls_printf(" failed\n");
    196 
    197 #if !defined(MBEDTLS_X509_REMOVE_INFO)
    198         mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "  ! ", flags);
    199 
    200         mbedtls_printf("%s\n", vrfy_buf);
    201 #endif
    202     } else {
    203         mbedtls_printf(" ok\n");
    204     }
    205 
    206     /*
    207      * 3. Write the GET request
    208      */
    209     mbedtls_printf("  > Write to server:");
    210     fflush(stdout);
    211 
    212     len = sprintf((char *) buf, GET_REQUEST);
    213 
    214     while ((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0) {
    215         if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
    216             mbedtls_printf(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret);
    217             goto exit;
    218         }
    219     }
    220 
    221     len = ret;
    222     mbedtls_printf(" %d bytes written\n\n%s", len, (char *) buf);
    223 
    224     /*
    225      * 7. Read the HTTP response
    226      */
    227     mbedtls_printf("  < Read from server:");
    228     fflush(stdout);
    229 
    230     do {
    231         len = sizeof(buf) - 1;
    232         memset(buf, 0, sizeof(buf));
    233         ret = mbedtls_ssl_read(&ssl, buf, len);
    234 
    235         if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
    236             continue;
    237         }
    238 
    239         if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
    240             mbedtls_printf("The return value %d from mbedtls_ssl_read() means that the server\n"
    241                            "closed the connection first. We're ok with that.\n",
    242                            MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY);
    243             break;
    244         }
    245 
    246         if (ret < 0) {
    247             mbedtls_printf("failed\n  ! mbedtls_ssl_read returned %d\n\n", ret);
    248             break;
    249         }
    250 
    251         if (ret == 0) {
    252             mbedtls_printf("\n\nEOF\n\n");
    253             break;
    254         }
    255 
    256         len = ret;
    257         mbedtls_printf(" %d bytes read\n\n%s", len, (char *) buf);
    258     } while (1);
    259 
    260     mbedtls_ssl_close_notify(&ssl);
    261 
    262     if (ret == 0 || ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
    263         exit_code = MBEDTLS_EXIT_SUCCESS;
    264     }
    265 
    266 exit:
    267 
    268 #ifdef MBEDTLS_ERROR_C
    269     if (exit_code != MBEDTLS_EXIT_SUCCESS) {
    270         char error_buf[100];
    271         mbedtls_strerror(ret, error_buf, 100);
    272         mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf);
    273     }
    274 #endif
    275 
    276     mbedtls_net_free(&server_fd);
    277     mbedtls_x509_crt_free(&cacert);
    278     mbedtls_ssl_free(&ssl);
    279     mbedtls_ssl_config_free(&conf);
    280     mbedtls_ctr_drbg_free(&ctr_drbg);
    281     mbedtls_entropy_free(&entropy);
    282 #if defined(MBEDTLS_USE_PSA_CRYPTO)
    283     mbedtls_psa_crypto_free();
    284 #endif /* MBEDTLS_USE_PSA_CRYPTO */
    285 
    286     mbedtls_exit(exit_code);
    287 }
    288 
    289 #endif /* configuration allows running this program */