Subversion Repositories Kolibri OS

Rev

Rev 9076 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  *  SSL client demonstration program
  3.  *
  4.  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  5.  *  SPDX-License-Identifier: GPL-2.0
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License along
  18.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  19.  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  *  This file is part of mbed TLS (https://tls.mbed.org)
  22.  */
  23.  
  24. #if !defined(MBEDTLS_CONFIG_FILE)
  25. #include "mbedtls/config.h"
  26. #else
  27. #include MBEDTLS_CONFIG_FILE
  28. #endif
  29.  
  30. #if defined(MBEDTLS_PLATFORM_C)
  31. #include "mbedtls/platform.h"
  32. #else
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #define mbedtls_time            time
  36. #define mbedtls_time_t          time_t
  37. #define mbedtls_fprintf         fprintf
  38. #define mbedtls_printf          printf
  39. #define mbedtls_exit            exit
  40. #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
  41. #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
  42. #endif /* MBEDTLS_PLATFORM_C */
  43.  
  44. #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) ||  \
  45.     !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
  46.     !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) ||         \
  47.     !defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C) || \
  48.     !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
  49. int main( void )
  50. {
  51.     mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
  52.            "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
  53.            "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
  54.            "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
  55.            "not defined.\n");
  56.     return( 0 );
  57. }
  58. #else
  59.  
  60. #include "mbedtls/net_sockets.h"
  61. #include "mbedtls/debug.h"
  62. #include "mbedtls/ssl.h"
  63. #include "mbedtls/entropy.h"
  64. #include "mbedtls/ctr_drbg.h"
  65. #include "mbedtls/error.h"
  66. #include "mbedtls/certs.h"
  67.  
  68. #include <string.h>
  69.  
  70. //#define SERVER_PORT "443"
  71. //#define SERVER_NAME "wikipedia.org"
  72. //#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
  73. char SERVER_PORT[16];
  74. char SERVER_NAME[128];
  75. char GET_REQUEST[512];
  76.  
  77. #define DEBUG_LEVEL 1
  78.  
  79.  
  80. static void my_debug( void *ctx, int level,
  81.                       const char *file, int line,
  82.                       const char *str )
  83. {
  84.     ((void) level);
  85.  
  86.     //mbedtls_fprintf( (FILE *) ctx, "%s:%04d: %s", file, line, str );
  87.     //fflush(  (FILE *) ctx  );
  88.     printf("%s:%04d: %s", file, line, str );
  89. }
  90.  
  91. int main( void )
  92. {
  93.         puts("Enter SERVER_NAME : ");
  94.         gets(SERVER_NAME);
  95.         puts("Enter SERVER_PORT : ");
  96.         gets(SERVER_PORT);
  97.         sprintf(GET_REQUEST, "GET / HTTP/1.1\r\nHost: %s\r\n\r\n", SERVER_NAME);
  98.  
  99.     int ret = 1, len;
  100.     int exit_code = MBEDTLS_EXIT_FAILURE;
  101.     mbedtls_net_context server_fd;
  102.     uint32_t flags;
  103.     unsigned char buf[1024];
  104.     const char *pers = "ssl_client1";
  105.  
  106.     mbedtls_entropy_context entropy;
  107.     mbedtls_ctr_drbg_context ctr_drbg;
  108.     mbedtls_ssl_context ssl;
  109.     mbedtls_ssl_config conf;
  110.     mbedtls_x509_crt cacert;
  111.  
  112. #if defined(MBEDTLS_DEBUG_C)
  113.     mbedtls_debug_set_threshold( DEBUG_LEVEL );
  114. #endif
  115.  
  116.     /*
  117.      * 0. Initialize the RNG and the session data
  118.      */
  119.     mbedtls_net_init( &server_fd );
  120.     mbedtls_ssl_init( &ssl );
  121.     mbedtls_ssl_config_init( &conf );
  122.     mbedtls_x509_crt_init( &cacert );
  123.     mbedtls_ctr_drbg_init( &ctr_drbg );
  124.  
  125.     mbedtls_printf( "\n  . Seeding the random number generator..." );
  126.     //fflush( stdout );
  127.  
  128.     mbedtls_entropy_init( &entropy );
  129.     if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
  130.                                (const unsigned char *) pers,
  131.                                strlen( pers ) ) ) != 0 )
  132.     {
  133.         mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
  134.         goto exit;
  135.     }
  136.  
  137.     mbedtls_printf( " ok\n" );
  138.  
  139.     /*
  140.      * 0. Initialize certificates
  141.      */
  142.     mbedtls_printf( "  . Loading the CA root certificate ..." );
  143.     //fflush( stdout );
  144.  
  145.     ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem,
  146.                           mbedtls_test_cas_pem_len );
  147.     if( ret < 0 )
  148.     {
  149.         mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
  150.         goto exit;
  151.     }
  152.  
  153.     mbedtls_printf( " ok (%d skipped)\n", ret );
  154.  
  155.     /*
  156.      * 1. Start the connection
  157.      */
  158.     mbedtls_printf( "  . Connecting to tcp/%s/%s...", SERVER_NAME, SERVER_PORT );
  159.     //fflush( stdout );
  160.  
  161.     if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME,
  162.                                          SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 )
  163.     {
  164.         mbedtls_printf( " failed\n  ! mbedtls_net_connect returned %d\n\n", ret );
  165.         goto exit;
  166.     }
  167.  
  168.     mbedtls_printf( " ok\n" );
  169.  
  170.     /*
  171.      * 2. Setup stuff
  172.      */
  173.     mbedtls_printf( "  . Setting up the SSL/TLS structure..." );
  174.     //fflush( stdout );
  175.  
  176.     if( ( ret = mbedtls_ssl_config_defaults( &conf,
  177.                     MBEDTLS_SSL_IS_CLIENT,
  178.                     MBEDTLS_SSL_TRANSPORT_STREAM,
  179.                     MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
  180.     {
  181.         mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
  182.         goto exit;
  183.     }
  184.  
  185.     mbedtls_printf( " ok\n" );
  186.  
  187.     /* OPTIONAL is not optimal for security,
  188.      * but makes interop easier in this simplified example */
  189.     mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
  190.     mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
  191.     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
  192.     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
  193.  
  194.     if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
  195.     {
  196.         mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret );
  197.         goto exit;
  198.     }
  199.  
  200.     if( ( ret = mbedtls_ssl_set_hostname( &ssl, SERVER_NAME ) ) != 0 )
  201.     {
  202.         mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
  203.         goto exit;
  204.     }
  205.  
  206.     mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
  207.  
  208.     /*
  209.      * 4. Handshake
  210.      */
  211.     mbedtls_printf( "  . Performing the SSL/TLS handshake..." );
  212.     //fflush( stdout );
  213.  
  214.     while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
  215.     {
  216.         if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
  217.         {
  218.             mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
  219.             goto exit;
  220.         }
  221.     }
  222.  
  223.     mbedtls_printf( " ok\n" );
  224.  
  225.     /*
  226.      * 5. Verify the server certificate
  227.      */
  228.     mbedtls_printf( "  . Verifying peer X.509 certificate..." );
  229.  
  230.     /* In real life, we probably want to bail out when ret != 0 */
  231.     if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 )
  232.     {
  233.         char vrfy_buf[512];
  234.  
  235.         mbedtls_printf( " failed\n" );
  236.  
  237.         mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );
  238.  
  239.         mbedtls_printf( "%s\n", vrfy_buf );
  240.     }
  241.     else
  242.         mbedtls_printf( " ok\n" );
  243.  
  244.     /*
  245.      * 3. Write the GET request
  246.      */
  247.     mbedtls_printf( "  > Write to server:" );
  248.     //fflush( stdout );
  249.  
  250.     len = sprintf( (char *) buf, GET_REQUEST );
  251.  
  252.     while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 )
  253.     {
  254.         if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
  255.         {
  256.             mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
  257.             goto exit;
  258.         }
  259.     }
  260.  
  261.     len = ret;
  262.     mbedtls_printf( " %d bytes written\n\n%s", len, (char *) buf );
  263.  
  264.     /*
  265.      * 7. Read the HTTP response
  266.      */
  267.     mbedtls_printf( "  < Read from server:" );
  268.     //fflush( stdout );
  269.  
  270.     do
  271.     {
  272.         len = sizeof( buf ) - 1;
  273.         memset( buf, 0, sizeof( buf ) );
  274.         ret = mbedtls_ssl_read( &ssl, buf, len );
  275.  
  276.         if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
  277.             continue;
  278.  
  279.         if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
  280.             break;
  281.  
  282.         if( ret < 0 )
  283.         {
  284.             mbedtls_printf( "failed\n  ! mbedtls_ssl_read returned %d\n\n", ret );
  285.             break;
  286.         }
  287.  
  288.         if( ret == 0 )
  289.         {
  290.             mbedtls_printf( "\n\nEOF\n\n" );
  291.             break;
  292.         }
  293.  
  294.         len = ret;
  295.         mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
  296.     }
  297.     while( 1 );
  298.  
  299.     mbedtls_ssl_close_notify( &ssl );
  300.  
  301.     exit_code = MBEDTLS_EXIT_SUCCESS;
  302.  
  303. exit:
  304.  
  305. #ifdef MBEDTLS_ERROR_C
  306.     if( exit_code != MBEDTLS_EXIT_SUCCESS )
  307.     {
  308.         char error_buf[100];
  309.         mbedtls_strerror( ret, error_buf, 100 );
  310.         mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf );
  311.     }
  312. #endif
  313.  
  314.     mbedtls_net_free( &server_fd );
  315.  
  316.     mbedtls_x509_crt_free( &cacert );
  317.     mbedtls_ssl_free( &ssl );
  318.     mbedtls_ssl_config_free( &conf );
  319.     mbedtls_ctr_drbg_free( &ctr_drbg );
  320.     mbedtls_entropy_free( &entropy );
  321.  
  322.  
  323.     return( exit_code );
  324. }
  325. #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
  326.           MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
  327.           MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C && MBEDTLS_CTR_DRBG_C &&
  328.           MBEDTLS_X509_CRT_PARSE_C */
  329.