888 lines
31 KiB
C
888 lines
31 KiB
C
/*!
|
|
\file ssl_client.c
|
|
\brief SSL client demonstration program for GD32W51x WiFi SDK
|
|
|
|
\version 2021-10-30, V1.0.0, firmware for GD32W51x
|
|
*/
|
|
|
|
/*
|
|
Copyright (c) 2021, GigaDevice Semiconductor Inc.
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright notice, this
|
|
list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
3. Neither the name of the copyright holder nor the names of its contributors
|
|
may be used to endorse or promote products derived from this software without
|
|
specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
|
OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "ssl_tz.h" /* must be included before mbedtls header file */
|
|
#include "mbedtls/platform.h"
|
|
#include "mbedtls/net_sockets.h"
|
|
#include "mbedtls/ssl.h"
|
|
#include "mbedtls/error.h"
|
|
#include "mbedtls/debug.h"
|
|
#include "mbedtls/ssl_ciphersuites.h"
|
|
#include "wrapper_os.h"
|
|
#include "init_rom.h"
|
|
#include <string.h>
|
|
|
|
#if defined(CONFIG_TZ_ENABLED)
|
|
#include "mbedtls_nsc.h"
|
|
#endif
|
|
|
|
#ifdef CONFIG_SSL_TEST
|
|
/*-----------------Options -----------------------*/
|
|
#define TLS_VERIFY_SRV_CERT 1
|
|
#define TLS_VERIFY_CLI_CERT 0
|
|
|
|
#define SERVER_PORT "443"
|
|
#define SERVER_NAME "www.baidu.com"
|
|
#define HTTP_PROTOCOL "HTTP/1.0\r\n"
|
|
|
|
/* TLS_CRT_[Chain Depth]_[Sign Algorithm]_[Key Len or Curve Name]_[Cert Digest Algorithm] */
|
|
#define TLS_CRT_NONE 0 //no cert
|
|
#define TLS_CRT_1_RSA_1024_SHA256 1 //rsa1
|
|
#define TLS_CRT_1_RSA_2048_SHA1 2 //rsa2
|
|
#define TLS_CRT_1_RSA_3072_SHA256 3 //rsa3
|
|
#define TLS_CRT_1_ECDSA_PRIME256V1_SHA256 4 //ecp1
|
|
#define TLS_CRT_1_ECDSA_SECP384R1_SHA384 5 //ecp2
|
|
#define TLS_CRT_1_ECDSA_BRAINP512R1_SHA512 6 //ecp3
|
|
#define TLS_CRT_1_ECDSA_SECP521R1_SHA512 7 //ecp4
|
|
#define TLS_CRT_3_RSA_2048_SHA512 8 //rsa_chain
|
|
#define TLS_CRT_3_ECDSA_SECP521R1_SHA512 9 //ecp_chain
|
|
#define BAIDU_CERT 10
|
|
#define TLS_CRT_MAX_INDEX 10
|
|
|
|
#define HTTPS_GET 1
|
|
#define HTTPS_HEAD 2
|
|
#define HTTPS_OPTIONS 3
|
|
#define HTTPS_TRACE 4
|
|
#define HTTPS_POST 5
|
|
|
|
#if (TLS_VERIFY_SRV_CERT || TLS_VERIFY_CLI_CERT)
|
|
#define TLS_CRT_USED
|
|
#include "ssl_certs.c"
|
|
#endif
|
|
|
|
static char server_host[128];
|
|
static char server_path[128];
|
|
static char server_port[8];
|
|
static char https_request_body[128];
|
|
#ifdef TLS_CRT_USED
|
|
static unsigned int cert_type;
|
|
#endif
|
|
unsigned int debug_level = 3;
|
|
unsigned int wait_srv_rsp = 1;
|
|
uint8_t https_method;
|
|
|
|
/*!
|
|
\brief owner debug function
|
|
\param[in] file: pointer to the file
|
|
\param[in] line: line value
|
|
\param[in] str: pointer to the string
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
static void my_debug( void *ctx, int level,
|
|
const char *file, int line,
|
|
const char *str )
|
|
{
|
|
((void) level);
|
|
printf("%s:%04d: %s", file, line, str );
|
|
}
|
|
/*!
|
|
\brief owner get random function
|
|
\param[in] p_rng:
|
|
\param[in] output_len: get random calue length
|
|
\param[out] output: pointer to the output value
|
|
\retval function run state(0: no error, other: have error)
|
|
*/
|
|
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
|
|
{
|
|
sys_random_bytes_get(output, output_len);
|
|
return 0;
|
|
}
|
|
#if TLS_VERIFY_SRV_CERT
|
|
/*!
|
|
\brief owner verify function
|
|
\param[in] data: pointer to the input value
|
|
\param[in] crt: pointer to the X.509 certificates structures
|
|
\param[in] depth: depth vlaue
|
|
\param[in] flags: pointer to the flag value
|
|
\param[out] output: pointer to the output value
|
|
\retval function run state(0: no error, other: have error)
|
|
*/
|
|
static int my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
|
|
{
|
|
char buf[1024];
|
|
((void) data);
|
|
|
|
printf("Verify requested for (Depth %d):\r\n", depth);
|
|
mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
|
|
printf("%s", buf);
|
|
|
|
if(((*flags) & MBEDTLS_X509_BADCERT_EXPIRED) != 0)
|
|
printf("server certificate has expired\r\n");
|
|
|
|
if(((*flags) & MBEDTLS_X509_BADCERT_REVOKED) != 0)
|
|
printf(" ! server certificate has been revoked\r\n");
|
|
|
|
if(((*flags) & MBEDTLS_X509_BADCERT_CN_MISMATCH) != 0)
|
|
printf(" ! CN mismatch\r\n");
|
|
|
|
if(((*flags) & MBEDTLS_X509_BADCERT_NOT_TRUSTED) != 0)
|
|
printf(" ! self-signed or not signed by a trusted CA\r\n");
|
|
|
|
if(((*flags) & MBEDTLS_X509_BADCRL_NOT_TRUSTED) != 0)
|
|
printf(" ! CRL not trusted\r\n");
|
|
|
|
if(((*flags) & MBEDTLS_X509_BADCRL_EXPIRED) != 0)
|
|
printf(" ! CRL expired\r\n");
|
|
|
|
if(((*flags) & MBEDTLS_X509_BADCERT_OTHER) != 0)
|
|
printf(" ! other (unknown) flag\r\n");
|
|
|
|
if((*flags) == 0)
|
|
printf(" Certificate verified without error flags\r\n");
|
|
|
|
return(0);
|
|
}
|
|
#endif
|
|
/* sizeof(mbedtls_net_context) = 4
|
|
sizeof(mbedtls_ssl_context) = 312
|
|
sizeof(mbedtls_ssl_config) = 208
|
|
sizeof(mbedtls_x509_crt) = 308
|
|
sizeof(mbedtls_pk_context) = 8
|
|
SSL client STACK = 2048 dword, high water mark = 1822 dword
|
|
*/
|
|
/*!
|
|
\brief ssl client
|
|
\param[in] arg: pointer to the input value
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void ssl_client(void *arg)
|
|
{
|
|
int ret, len;
|
|
mbedtls_net_context server_fd;
|
|
unsigned int flags;
|
|
unsigned char buf[1025];
|
|
|
|
mbedtls_ssl_context ssl;
|
|
mbedtls_ssl_config conf;
|
|
|
|
#ifdef TLS_CRT_USED
|
|
int need_cert = FALSE;
|
|
#endif
|
|
#if TLS_VERIFY_SRV_CERT
|
|
mbedtls_x509_crt ca_cert;
|
|
#endif
|
|
#if TLS_VERIFY_CLI_CERT
|
|
mbedtls_x509_crt cli_cert;
|
|
mbedtls_pk_context cli_key;
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_DEBUG_C)
|
|
mbedtls_debug_set_threshold( debug_level );
|
|
#endif
|
|
|
|
/*
|
|
* 0. Initialize the RNG and the session data
|
|
*/
|
|
#ifndef CONFIG_TZ_ENABLED // MBL has called it yet
|
|
mbedtls_ecp_curve_val_init();
|
|
#endif
|
|
mbedtls_net_init( &server_fd );
|
|
mbedtls_ssl_init( &ssl );
|
|
mbedtls_ssl_config_init( &conf );
|
|
#if TLS_VERIFY_SRV_CERT
|
|
mbedtls_x509_crt_init( &ca_cert );
|
|
#endif
|
|
#if TLS_VERIFY_CLI_CERT
|
|
mbedtls_x509_crt_init( &cli_cert );
|
|
mbedtls_pk_init( &cli_key );
|
|
#endif
|
|
|
|
printf( " . Seeding the random number generator...\r\n" );
|
|
|
|
/*
|
|
* 1. Initialize certificates
|
|
*/
|
|
#ifdef TLS_CRT_USED
|
|
need_cert = ssl_client_crt_init(cert_type);
|
|
#endif
|
|
#if TLS_VERIFY_SRV_CERT
|
|
if(need_cert){
|
|
printf( " . Loading the CA root certificate ..." );
|
|
|
|
ret = mbedtls_x509_crt_parse(&ca_cert, (const unsigned char *)ca_cert_str, strlen(ca_cert_str) + 1);
|
|
if( ret < 0 ){
|
|
printf( " failed\r\n ! mbedtls_x509_crt_parse returned -0x%x\r\n", -ret );
|
|
goto exit;
|
|
}
|
|
|
|
printf( " ok (%d skipped)\r\n", ret );
|
|
}
|
|
#endif
|
|
|
|
#if TLS_VERIFY_CLI_CERT
|
|
if(need_cert){
|
|
printf( " . Loading the Client certificate ..." );
|
|
|
|
ret = mbedtls_x509_crt_parse(&cli_cert, (const unsigned char *)cli_cert_str, strlen(cli_cert_str) + 1);
|
|
if( ret < 0 ){
|
|
printf( " failed\r\n ! mbedtls_x509_crt_parse returned -0x%x\r\n", -ret );
|
|
goto exit;
|
|
}
|
|
|
|
printf( " ok (%d skipped)\r\n", ret );
|
|
|
|
printf( " . Loading the Client key ..." );
|
|
|
|
ret = mbedtls_pk_parse_key(&cli_key, (const unsigned char *)cli_key_str, strlen(cli_key_str) + 1, NULL, 0);
|
|
if( ret < 0 ){
|
|
printf( " failed\r\n ! mbedtls_pk_parse_key returned -0x%x\r\n", -ret );
|
|
goto exit;
|
|
}
|
|
|
|
printf( " ok (%d skipped)\r\n", ret );
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* 2. Start the connection
|
|
*/
|
|
printf( " . Connecting to tcp/%s/%s...", server_host, server_port );
|
|
|
|
if( ( ret = mbedtls_net_connect( &server_fd, server_host,
|
|
server_port, MBEDTLS_NET_PROTO_TCP ) ) != 0 )
|
|
{
|
|
printf( " failed\r\n ! mbedtls_net_connect returned %d\r\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
printf( " ok\r\n" );
|
|
|
|
/*
|
|
* 3. Setup stuff
|
|
*/
|
|
printf( " . Setting up the SSL/TLS structure..." );
|
|
|
|
if( ( ret = mbedtls_ssl_config_defaults( &conf,
|
|
MBEDTLS_SSL_IS_CLIENT,
|
|
MBEDTLS_SSL_TRANSPORT_STREAM,
|
|
MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
|
|
{
|
|
printf( " failed\r\n ! mbedtls_ssl_config_defaults returned %d\r\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
printf( " ok\r\n" );
|
|
|
|
/* OPTIONAL is not optimal for security,
|
|
* but makes interop easier in this simplified example */
|
|
#if defined(CONFIG_TZ_ENABLED)
|
|
mbedtls_ssl_conf_rng( &conf, mbedtls_random_nsc, NULL);
|
|
#else
|
|
mbedtls_ssl_conf_rng( &conf, my_random, NULL);
|
|
#endif
|
|
mbedtls_ssl_conf_dbg( &conf, my_debug, NULL );
|
|
|
|
#if TLS_VERIFY_SRV_CERT
|
|
if(need_cert)
|
|
{
|
|
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
|
mbedtls_ssl_conf_ca_chain(&conf, &ca_cert, NULL);
|
|
#if defined(CONFIG_TZ_ENABLED)
|
|
mbedtls_ssl_conf_verify(&conf, mbedtls_verify_nsc, NULL);
|
|
#else
|
|
mbedtls_ssl_conf_verify(&conf, my_verify, NULL);
|
|
#endif
|
|
}else{
|
|
mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE );
|
|
}
|
|
#else
|
|
mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE );
|
|
#endif
|
|
#if TLS_VERIFY_CLI_CERT
|
|
if(need_cert)
|
|
mbedtls_ssl_conf_own_cert(&conf, &cli_cert, &cli_key);
|
|
#endif
|
|
|
|
if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
|
|
{
|
|
printf( " failed\r\n ! mbedtls_ssl_setup returned %d\r\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
if( ( ret = mbedtls_ssl_set_hostname( &ssl, server_host ) ) != 0 )
|
|
{
|
|
printf( " failed\r\n ! mbedtls_ssl_set_hostname returned %d\r\n", ret );
|
|
goto exit;
|
|
}
|
|
|
|
mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
|
|
|
|
/*
|
|
* 4. Handshake
|
|
*/
|
|
printf( " . Performing the SSL/TLS handshake..." );
|
|
|
|
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
|
|
{
|
|
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
|
{
|
|
printf( " failed\r\n ! mbedtls_ssl_handshake returned -0x%x\r\n", -ret );
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
printf( " ok\r\n" );
|
|
|
|
/*
|
|
* 5. Verify the server certificate
|
|
*/
|
|
printf( " . Verifying peer X.509 certificate..." );
|
|
|
|
/* In real life, we probably want to bail out when ret != 0 */
|
|
if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 )
|
|
{
|
|
char vrfy_buf[512];
|
|
|
|
printf( " failed\r\n" );
|
|
|
|
mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags );
|
|
|
|
printf( "%s\r\n", vrfy_buf );
|
|
}
|
|
else
|
|
printf( " ok\r\n" );
|
|
|
|
if (https_method > 0)
|
|
{
|
|
/*
|
|
* 6. Write the HTTP request
|
|
*/
|
|
printf(" > Write to server:");
|
|
|
|
switch (https_method)
|
|
{
|
|
case HTTPS_GET:
|
|
len = sprintf((char *)buf, "%s%s%s %s%s", "GET https://",server_host,server_path,HTTP_PROTOCOL,"\r\n");
|
|
break;
|
|
case HTTPS_HEAD:
|
|
len = sprintf((char *)buf, "%s%s%s %s%s", "HEAD https://",server_host,server_path,HTTP_PROTOCOL,"\r\n");
|
|
break;
|
|
case HTTPS_OPTIONS:
|
|
len = sprintf((char *)buf, "%s%s%s %s%s", "OPTIONS https://",server_host,server_path,HTTP_PROTOCOL,"\r\n");
|
|
break;
|
|
case HTTPS_TRACE:
|
|
len = sprintf((char *)buf, "%s%s%s %s%s", "TRACE https://",server_host,server_path,HTTP_PROTOCOL,"\r\n");
|
|
break;
|
|
case HTTPS_POST:
|
|
len = sprintf((char *)buf, "%s%s%s %s%s%u%s%s", "POST https://",server_host,server_path,HTTP_PROTOCOL,"Content-Length:",strlen(https_request_body),"\r\nContent-Type:application/x-www-form-urlencoded\r\n\r\n",https_request_body);
|
|
break;
|
|
default:
|
|
len = sprintf((char *)buf, "%s%s%s %s%s", "HEAD https://",server_host,server_path,HTTP_PROTOCOL,"\r\n");
|
|
break;
|
|
}
|
|
|
|
while ((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0)
|
|
{
|
|
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
|
|
{
|
|
printf(" failed\r\n ! mbedtls_ssl_write returned %d\r\n", ret);
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
len = ret;
|
|
printf(" %d bytes written\r\n%s\r\n", len, (char *)buf);
|
|
|
|
/*
|
|
* 7. Read the HTTP response
|
|
*/
|
|
#if 1
|
|
printf(" < Read from server:\r\n");
|
|
do
|
|
{
|
|
len = sizeof(buf) - 1;
|
|
memset(buf, 0, sizeof(buf));
|
|
ret = mbedtls_ssl_read(&ssl, buf, len);
|
|
|
|
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)
|
|
continue;
|
|
|
|
if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
|
|
break;
|
|
|
|
if (ret < 0)
|
|
{
|
|
printf("failed\r\n ! mbedtls_ssl_read returned %d\r\n", ret);
|
|
break;
|
|
}
|
|
|
|
if (ret == 0)
|
|
{
|
|
printf("\r\nEOF\r\n");
|
|
break;
|
|
}
|
|
|
|
len = ret;
|
|
printf(" %d bytes read\r\n%s", len, (char *)buf);
|
|
} while (1);
|
|
#else
|
|
if (wait_srv_rsp)
|
|
{
|
|
printf(" < Read from server:\r\n");
|
|
len = sizeof(buf) - 1;
|
|
memset(buf, 0, sizeof(buf));
|
|
ret = mbedtls_ssl_read(&ssl, buf, len);
|
|
if (ret < 0)
|
|
{
|
|
printf("\r\nfailed\r\n ! mbedtls_ssl_read returned %d\r\n", ret);
|
|
}
|
|
else if (ret == 0)
|
|
{
|
|
printf("\r\nEOF\r\n");
|
|
}
|
|
else
|
|
{
|
|
printf("\r\n %d bytes read\r\n%s\r\n", ret, (char *)buf);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
mbedtls_ssl_close_notify( &ssl );
|
|
|
|
exit:
|
|
|
|
#ifdef MBEDTLS_ERROR_C
|
|
if( ret != 0 )
|
|
{
|
|
char error_buf[100];
|
|
mbedtls_strerror( ret, error_buf, 100 );
|
|
printf("Last error was: %d - %s\r\n", ret, error_buf );
|
|
}
|
|
#endif
|
|
mbedtls_net_free( &server_fd );
|
|
#if TLS_VERIFY_SRV_CERT
|
|
mbedtls_x509_crt_free( &ca_cert );
|
|
#endif
|
|
#if TLS_VERIFY_CLI_CERT
|
|
mbedtls_x509_crt_free( &cli_cert );
|
|
mbedtls_pk_free( &cli_key );
|
|
#endif
|
|
mbedtls_ssl_free( &ssl );
|
|
mbedtls_ssl_config_free( &conf );
|
|
|
|
printf("\r\nExit ssl client task: stack high water mark = %d\r\n", sys_stack_free_get(NULL));
|
|
|
|
sys_task_delete(NULL);
|
|
}
|
|
|
|
|
|
#define MAX_CIPHERSUITE_SET_NUM 8
|
|
#define MAX_CIPHERSUITE_SET_MEMBER 8
|
|
static int ciphersuite_sets[MAX_CIPHERSUITE_SET_NUM][MAX_CIPHERSUITE_SET_MEMBER]=
|
|
{
|
|
/* RSA */
|
|
{
|
|
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, //0x2F
|
|
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, //0x3C /**< TLS 1.2 */
|
|
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, //0x3D /**< TLS 1.2 */
|
|
MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, //0x9C /**< TLS 1.2 */
|
|
MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, //0x9D /**< TLS 1.2 */
|
|
},
|
|
/* ECDH */
|
|
{
|
|
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, //0xC025 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, //0xC026 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, //0xC029 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, //0xC02A /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, //0xC02D /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, //0xC02E /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, //0xC031 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, //0xC032 /**< TLS 1.2 */
|
|
},
|
|
/* ECDHE */
|
|
{
|
|
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, //0xC023 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, //0xC024 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, //0xC027 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, //0xC028 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, //0xC02B /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, //0xC02C /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, //0xC02F /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, //0xC030 /**< TLS 1.2 */
|
|
},
|
|
/* CAMELLIA */
|
|
{
|
|
MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, //0xC07A /**< TLS 1.2 */
|
|
MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, //0xC07B /**< TLS 1.2 */
|
|
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, //0xC07C /**< TLS 1.2 */
|
|
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, //0xC07D /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, //0xC088 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, //0xC089 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, //0xC08C /**< TLS 1.2 */
|
|
MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, //0xC08D /**< TLS 1.2 */
|
|
},
|
|
/* CCM */
|
|
{
|
|
MBEDTLS_TLS_RSA_WITH_AES_128_CCM, //0xC09C /**< TLS 1.2 */
|
|
MBEDTLS_TLS_RSA_WITH_AES_256_CCM, //0xC09D /**< TLS 1.2 */
|
|
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, //0xC09E /**< TLS 1.2 */
|
|
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, //0xC09F /**< TLS 1.2 */
|
|
MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, //0xC0A0 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, //0xC0A1 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, //0xC0A2 /**< TLS 1.2 */
|
|
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, //0xC0A3 /**< TLS 1.2 */
|
|
},
|
|
/* PSK */
|
|
{
|
|
MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, //0x8A
|
|
MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, //0x8B
|
|
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, //0x8C
|
|
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, //0x8D
|
|
MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, //0x92
|
|
MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, //0x93
|
|
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, //0x94
|
|
MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, //0x95
|
|
},
|
|
/* 3DES */
|
|
{
|
|
MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, //0x0A
|
|
MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, //0x16
|
|
MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, //0x8F
|
|
MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, //0x93
|
|
MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, //0xC003
|
|
MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, //0xC008
|
|
MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, //0xC00D
|
|
MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, //0xC012
|
|
},
|
|
/* RC4 */
|
|
{
|
|
MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, //0x8E
|
|
MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, //0x92
|
|
MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, //0xC002
|
|
MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, //0xC007
|
|
MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, //0xC00C
|
|
MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, //0xC00C
|
|
},
|
|
};
|
|
unsigned int ciphersuite_pref_count;
|
|
extern int ciphersuite_preference_array[MAX_CIPHERSUITE_PREFERENCE_ARRAY_LEN];
|
|
extern const int ciphersuite_preference_default[];
|
|
/*!
|
|
\brief initialize mbedtls ciphersuite preference
|
|
\param[in] none
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
static void mbedtls_cs_pref_init(void)
|
|
{
|
|
ciphersuite_pref_count = MAX_CIPHERSUITE_PREFERENCE_ARRAY_LEN;
|
|
memcpy((void *)ciphersuite_preference_array, ciphersuite_preference_default, MAX_CIPHERSUITE_PREFERENCE_ARRAY_LEN);
|
|
}
|
|
/*!
|
|
\brief clear mbedtls ciphersuite preference
|
|
\param[in] none
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
static void mbedtls_cs_pref_clear(void)
|
|
{
|
|
ciphersuite_pref_count = 0;
|
|
memset((void *)ciphersuite_preference_array, 0, sizeof(ciphersuite_preference_array));
|
|
}
|
|
/*!
|
|
\brief add mbedtls ciphersuite preference
|
|
\param[in] id: id want to add
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
static void mbedtls_cs_pref_add(int id)
|
|
{
|
|
ciphersuite_preference_array[ciphersuite_pref_count++] = id;
|
|
}
|
|
/*!
|
|
\brief dump mbedtls ciphersuite preference
|
|
\param[in] none
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
static void mbedtls_cs_pref_dump(void)
|
|
{
|
|
int i = 0, print_n = ciphersuite_pref_count;
|
|
printf("\r\nCiphersuite Preference(%d):", ciphersuite_pref_count);
|
|
if(print_n > 10)
|
|
print_n = 10;
|
|
for(i=0; i<print_n; i++)
|
|
{
|
|
printf("\r\n\t0x%x - %s", ciphersuite_preference_array[i], mbedtls_ssl_get_ciphersuite_name(ciphersuite_preference_array[i]));
|
|
}
|
|
printf("\r\n");
|
|
}
|
|
|
|
/*!
|
|
\brief set cipher suite parse
|
|
\param[in] arg: pointer to the input value
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
void parse_cipher_suite_set(char *arg)
|
|
{
|
|
int setid = atoi(arg);
|
|
int i = 0;
|
|
|
|
if(setid < MAX_CIPHERSUITE_SET_NUM)
|
|
{
|
|
mbedtls_cs_pref_clear();
|
|
for(i=0; i<MAX_CIPHERSUITE_SET_MEMBER; i++)
|
|
{
|
|
if(ciphersuite_sets[setid][i] != 0)
|
|
mbedtls_cs_pref_add(ciphersuite_sets[setid][i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief parse cipher suite
|
|
\param[in] arg: pointer to the input value
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
static void cipher_suites_parse(char *arg)
|
|
{
|
|
char buf[64];
|
|
char *p, *q, *endptr;
|
|
uint32_t id;
|
|
|
|
if(strlen(arg) > sizeof(buf)){
|
|
printf("\rThe input ciphersuite string is too long(%d).\r\n", strlen(arg));
|
|
return;
|
|
}
|
|
mbedtls_cs_pref_clear();
|
|
strcpy(buf, arg);
|
|
q = buf;
|
|
while(*q != '\0'){
|
|
p = q;
|
|
while((*q != ',')&&(*q != '\0')) q++;
|
|
if(*q == ','){
|
|
*q = '\0';
|
|
q++;
|
|
}
|
|
id = (uint32_t)strtoul(p, &endptr, 16);
|
|
if(((id & 0xFFFFFF00) == 0xC000) || ((id & 0xFFFFFF00) == 0x00))
|
|
mbedtls_cs_pref_add(id);
|
|
};
|
|
}
|
|
|
|
#ifdef TLS_CRT_USED
|
|
/*!
|
|
\brief parse certificates type
|
|
\param[in] arg: pointer to the input value
|
|
\param[out] none
|
|
\retval none
|
|
*/
|
|
static int cert_type_parse(char *arg)
|
|
{
|
|
if(strcmp(arg, "rsa1") == 0){
|
|
cert_type = TLS_CRT_1_RSA_1024_SHA256;
|
|
}else if(strcmp(arg, "rsa2") == 0){
|
|
cert_type = TLS_CRT_1_RSA_2048_SHA1;
|
|
}else if(strcmp(arg, "rsa3") == 0){
|
|
cert_type = TLS_CRT_1_RSA_3072_SHA256;
|
|
}else if(strcmp(arg, "ecp1") == 0){
|
|
cert_type = TLS_CRT_1_ECDSA_PRIME256V1_SHA256;
|
|
}else if(strcmp(arg, "ecp2") == 0){
|
|
cert_type = TLS_CRT_1_ECDSA_SECP384R1_SHA384;
|
|
}else if(strcmp(arg, "ecp3") == 0){
|
|
cert_type = TLS_CRT_1_ECDSA_BRAINP512R1_SHA512;
|
|
}else if(strcmp(arg, "ecp4") == 0){
|
|
cert_type = TLS_CRT_1_ECDSA_SECP521R1_SHA512;
|
|
}else if(strcmp(arg, "rsa_chain") == 0){
|
|
cert_type = TLS_CRT_3_RSA_2048_SHA512;
|
|
}else if(strcmp(arg, "ecp_chain") == 0){
|
|
cert_type = TLS_CRT_3_ECDSA_SECP521R1_SHA512;
|
|
}else if(strcmp(arg, "baidu") == 0){
|
|
cert_type = BAIDU_CERT;
|
|
}else{
|
|
printf("\rThe input cert type is unknown(%s).\r\n", arg);
|
|
return -1;
|
|
}
|
|
//printf("\r\n%s(): arg = %s cert_type = %d\r\n", __func__, arg, cert_type);
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static void parse_request_method(char *arg)
|
|
{
|
|
if(strcmp(arg, "get") == 0){
|
|
https_method = HTTPS_GET;
|
|
}else if(strcmp(arg, "head") == 0){
|
|
https_method = HTTPS_HEAD;
|
|
}else if(strcmp(arg, "options") == 0){
|
|
https_method = HTTPS_OPTIONS;
|
|
}else if(strcmp(arg, "trace") == 0){
|
|
https_method = HTTPS_TRACE;
|
|
}else if(strcmp(arg, "post") == 0){
|
|
https_method = HTTPS_POST;
|
|
}else{
|
|
printf("\rThe input request method is unknown(%s).\r\n", arg);
|
|
}
|
|
}
|
|
|
|
/* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
|
|
MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
|
|
MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C && MBEDTLS_CTR_DRBG_C &&
|
|
MBEDTLS_X509_CRT_PARSE_C */
|
|
/*!
|
|
\brief command of ssl client
|
|
\param[in] argc: counter of input argument
|
|
\param[out] argv: pointer to the input argument
|
|
\retval none
|
|
*/
|
|
void cmd_ssl_client(int argc, char **argv)
|
|
{
|
|
int arg_cnt = 2;
|
|
#ifdef TLS_CRT_USED
|
|
int ret = 0;
|
|
cert_type = TLS_CRT_NONE;
|
|
#endif
|
|
debug_level = 1;
|
|
wait_srv_rsp = 1;
|
|
https_method = 0;
|
|
memset(server_path,0,sizeof(server_path));
|
|
memset(https_request_body,0,sizeof(https_request_body));
|
|
strcpy(server_host, SERVER_NAME);
|
|
strcpy(server_port, SERVER_PORT);
|
|
|
|
//cmd_mem_status(0, NULL);
|
|
|
|
if(argc < arg_cnt){
|
|
goto PrintHelp;
|
|
}
|
|
|
|
while (arg_cnt <= argc) {
|
|
if (strcmp(argv[arg_cnt-1], "-h") == 0) {
|
|
if (argc > arg_cnt)
|
|
snprintf(server_host, sizeof(server_host), "%s", argv[arg_cnt]);
|
|
arg_cnt += 2;
|
|
} else if (strcmp(argv[arg_cnt-1], "-p") == 0) {
|
|
if (argc > arg_cnt)
|
|
snprintf(server_port, sizeof(server_port), "%s", argv[arg_cnt]);
|
|
arg_cnt += 2;
|
|
} else if (strcmp(argv[arg_cnt-1], "-cs") == 0) {
|
|
if (argc > arg_cnt)
|
|
cipher_suites_parse(argv[arg_cnt]);
|
|
arg_cnt += 2;
|
|
} else if (strcmp(argv[arg_cnt-1], "-ss") == 0) {
|
|
if (argc > arg_cnt)
|
|
parse_cipher_suite_set(argv[arg_cnt]);
|
|
arg_cnt += 2;
|
|
} else if (strcmp(argv[arg_cnt-1], "-cert") == 0) {
|
|
#ifdef TLS_CRT_USED
|
|
if (argc > arg_cnt)
|
|
ret = cert_type_parse(argv[arg_cnt]);
|
|
if (ret < 0)
|
|
goto PrintHelp;
|
|
#endif
|
|
arg_cnt += 2;
|
|
} else if (strcmp(argv[arg_cnt-1], "-default") == 0) {
|
|
mbedtls_cs_pref_init();
|
|
arg_cnt += 1;
|
|
} else if (strcmp(argv[arg_cnt-1], "-debug") == 0) {
|
|
if (argc > arg_cnt)
|
|
debug_level = atoi(argv[arg_cnt]);
|
|
arg_cnt += 2;
|
|
} else if (strcmp(argv[arg_cnt-1], "-norsp") == 0) {
|
|
wait_srv_rsp = 0;
|
|
arg_cnt += 1;
|
|
} else if (strcmp(argv[arg_cnt-1], "-path") == 0) {
|
|
if (argc > arg_cnt)
|
|
snprintf(server_path, sizeof(server_path), "%s", argv[arg_cnt]);
|
|
arg_cnt += 2;
|
|
} else if (strcmp(argv[arg_cnt-1], "-method") == 0) {
|
|
if (argc > arg_cnt)
|
|
parse_request_method(argv[arg_cnt]);
|
|
arg_cnt += 2;
|
|
} else if (strcmp(argv[arg_cnt-1], "-postdata") == 0) {
|
|
if (argc > arg_cnt)
|
|
snprintf(https_request_body, sizeof(https_request_body), "%s", argv[arg_cnt]);
|
|
arg_cnt += 2;
|
|
} else {
|
|
printf("\r\nFormat error.");
|
|
goto PrintHelp;
|
|
}
|
|
}
|
|
|
|
printf("Server Host: %s Port: %s\r\n", server_host, server_port);
|
|
mbedtls_cs_pref_dump();
|
|
|
|
if (NULL == sys_task_create(NULL, (const uint8_t *)"ssl_client", NULL,
|
|
SSL_CLIENT_TASK_STK_SIZE, 0, SSL_CLIENT_TASK_PRIO,
|
|
(task_func_t)ssl_client, NULL)) {
|
|
printf("ERROR: Create ssl client task failed\r\n");
|
|
}
|
|
|
|
return;
|
|
|
|
PrintHelp:
|
|
printf("Usage: %s [-h Host] [-p Port] [-cs CiperSuite] [-ss cipherSuiteSet] [-cert CertType] [-path Path] [-method Method] [-postdata Postdata]\r\n", argv[0]);
|
|
printf("Example:\r\n");
|
|
printf("\r\n\t\t%s -h www.baidu.com", argv[0]);
|
|
printf("\r\n\t\t%s -h 192.168.3.100 -p 4433", argv[0]);
|
|
printf("\r\n\t\t%s -h www.baidu.com -cs c02f", argv[0]);
|
|
printf("\r\n\t\t%s -h www.baidu.com -cs 3c,3d", argv[0]);
|
|
printf("\r\n\t\t%s -h www.baidu.com -ss 0", argv[0]);
|
|
printf("\r\n\t\t%s -default", argv[0]);
|
|
printf("\r\n\t\t%s -h 192.168.3.100 -p 4433 -cert rsa1", argv[0]);
|
|
printf("\r\n\t\t%s -h 192.168.3.100 -p 4433 -cert ecp_chain", argv[0]);
|
|
printf("\r\n\t\t%s -h passport.jd.com -p 443 -method post -path /new/login.aspx -postdata username=werty&password=erfgss", argv[0]);
|
|
printf("\rOption:\r\n");
|
|
printf("\r\n\t\t-h host: server host name or ip");
|
|
printf("\r\n\t\t-p port: server port");
|
|
printf("\r\n\t\t-cs cipersuite: ciphersuite number");
|
|
printf("\r\n\t\t\t\t3C - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256");
|
|
printf("\r\n\t\t-ss cipersuiteset: ciphersuite set number 0 - 7");
|
|
printf("\r\n\t\t\t\t0 - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256");
|
|
printf("\r\n\t\t\t\t - MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256");
|
|
printf("\r\n\t\t\t\t - MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA");
|
|
printf("\r\n\t\t-cert type: type is choosed from {rsa1, rsa2, rsa3, ecp1, ecp2, ecp3, ecp4, rsa_chain, ecp_chain}");
|
|
printf("\r\n\t\t\t\trsa1 - TLS_CRT_1_RSA_1024_SHA256");
|
|
printf("\r\n\t\t\t\trsa2 - TLS_CRT_1_RSA_2048_SHA1");
|
|
printf("\r\n\t\t\t\trsa3 - TLS_CRT_1_RSA_3072_SHA256");
|
|
printf("\r\n\t\t\t\tecp1 - TLS_CRT_1_ECDSA_PRIME256V1_SHA256");
|
|
printf("\r\n\t\t\t\tecp2 - TLS_CRT_1_ECDSA_SECP384R1_SHA384");
|
|
printf("\r\n\t\t\t\tecp3 - TLS_CRT_1_ECDSA_BRAINP512R1_SHA512");
|
|
printf("\r\n\t\t\t\tecp4 - TLS_CRT_1_ECDSA_SECP521R1_SHA512");
|
|
printf("\r\n\t\t\t\trsa_chain - TLS_CRT_3_RSA_2048_SHA512");
|
|
printf("\r\n\t\t\t\tecp_chain - TLS_CRT_3_ECDSA_SECP521R1_SHA512");
|
|
printf("\r\n\t\t-path path: path of url");
|
|
printf("\r\n\t\t-method method: method of http request: head, get, options, trace, post");
|
|
printf("\r\n\t\t\t\tif method is post, must use -postdata option");
|
|
printf("\r\n\t\t-postdata postdata: request data of http request, only use when http request method is post");
|
|
printf("\r\n");
|
|
return;
|
|
}
|
|
|
|
#endif //CONFIG_SSL_TEST
|