Hello,
I'd like to run client https with mbedTLS, by using my k64f board and SDK examples - "liwp_httpssrv_mbedTLS_bm"
Sth like How To: Secure e-mail client (SMTP + SSL) with KSDK1.3 + WolfSSL for FRDM-K64F.
I looking for some examples or documentation for that. (client https with mbedTLS for k64f)
I think that basic sending/receiving data will help me.
Regards,
Bony
Hello again,
jingpan, should I use the "mbedtls_net_send" and "mbedtls_net_send" from example "lwip_httpssrv_mbedTLS_bm"???
I think I'am rly close to the solution, but still it's not working for me.
Hi Bony,
No, I don't think so.
Regards,
Jing
Hi jingpan,
Could You suggest, what is the problem with receiving data by mbedtls_ssl_set_bio receive callback?
I can send data by using mbedtls_ssl_set_bio send callback - "Client Hello".
Then I should receive Server Hello (with certificate, like on the screen below)
receive callback is not receiving this data, handshaking returns error and then my other callback function (which I make while testing) receive exactly this "Server Hello":
static err_t
http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
tcp_recved(pcb, p->tot_len);
return ERR_OK;
}
Why receive callback (setting by mbedtls_ssl_set_bio) can't receives this data?
You know any procedure of receiving (by using receive callback)?
Thanks for all suggestions!
Bony X
Hi Bony,
I am trying to build the same Https client for Https Server(in sample project).
Could you share some information with your final step? How did you fix it?
Thanks,
Christie
Hi,
It seems you can't use the functions in net_sockets.c without OS. All the functions in net_sockets.c is prohibited by a definition "MBEDTLS_NET_C". This definition should be defined in ksdk_mbedtls_config.h. But it says "This module only works on POSIX/Unix (including Linux, BSD and OS X) and Windows. For other platforms, you'll want to disable it, and write your own networking callbacks to be passed to \c mbedtls_ssl_set_bio()."
Regards,
Jing
jingpan napisał(-a):
"This module only works on POSIX/Unix (including Linux, BSD and OS X) and Windows. For other platforms, you'll want to disable it, and write your own networking callbacks to be passed to \c mbedtls_ssl_set_bio()."
Yes, I found it inside config.h file.
jingpan napisał(-a):
For other platforms, you'll want to disable it, and write your own networking callbacks to be passed to \c mbedtls_ssl_set_bio()."
I'm working on it now.
Hi Bony,
I can't find any documentation like the link you gave. But there is a readme in the project's directory. It also shows the test step. If you want more information of mbedTLS, please visit https://tls.mbed.org/kb/how-to/mbedtls-tutorial.
Regards,
Jing
Great, Thank u!
Now I have some problems with fonctions from file "net_sockets.c"
e.g. mbedtls_net_init and mbedtls_net_connect. "Still undefined reference to ..."
I imported the SDK example - "lwip_httpssrv_mbedTLS_bm" and changed "main.c" (there it's called lwip_httpssrv_mbedTLS_bm.c)
I pasted the example from tutorial and included missing files ("net_socket.h) but still the same problem. (net_sockets.h/c not visible ? )
Can I attach my project?
Below "main.c"
#include "lwip/opt.h"
#include "lwip/apps/httpd.h"
#include "lwip/timeouts.h"
#include "lwip/init.h"
#include "netif/ethernet.h"
#include "ethernetif.h"
#include "board.h"
#include "httpd_mbedtls.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/certs.h"
#include "mbedtls/x509.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_cache.h"
#include "mbedtls/debug.h"
#if FSL_FEATURE_SOC_LTC_COUNT
#include "fsl_ltc.h"
#endif
#if FSL_FEATURE_SOC_TRNG_COUNT
#include "fsl_trng.h"
#elif FSL_FEATURE_SOC_RNG_COUNT
#include "fsl_rnga.h"
#endif
#include "fsl_device_registers.h"
#include "pin_mux.h"
#include "clock_config.h"
//#include "platform.h"
//#include "mbedTLS/include/mbedtls/net_sockets.h"
#include <platform.h>
#include <mbedTLS/include/mbedtls/net_sockets.h>
/*******************************************************************************
* Definitions
******************************************************************************/
/* IP address configuration. */
#define configIP_ADDR0 192
#define configIP_ADDR1 168
#define configIP_ADDR2 0
#define configIP_ADDR3 115
/* Netmask configuration. */
#define configNET_MASK0 255
#define configNET_MASK1 255
#define configNET_MASK2 255
#define configNET_MASK3 0
/* Gateway address configuration. */
#define configGW_ADDR0 192
#define configGW_ADDR1 168
#define configGW_ADDR2 0
#define configGW_ADDR3 1
/* MAC address configuration. */
#define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11}
/* Address of PHY interface. */
#define EXAMPLE_PHY_ADDRESS BOARD_ENET0_PHY_ADDRESS
/* System clock name. */
#define EXAMPLE_CLOCK_NAME kCLOCK_CoreSysClk
/* GPIO pin configuration. */
#define BOARD_LED_GPIO BOARD_LED_RED_GPIO
#define BOARD_LED_GPIO_PIN BOARD_LED_RED_GPIO_PIN
#define BOARD_SW_GPIO BOARD_SW3_GPIO
#define BOARD_SW_GPIO_PIN BOARD_SW3_GPIO_PIN
#define BOARD_SW_PORT BOARD_SW3_PORT
#define BOARD_SW_IRQ BOARD_SW3_IRQ
#define BOARD_SW_IRQ_HANDLER BOARD_SW3_IRQ_HANDLER
#define SERVER_PORT "4433"
#define SERVER_NAME "localhost"
#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
#define DEBUG_LEVEL 1
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#include <stdlib.h>
#define mbedtls_time time
#define mbedtls_time_t time_t
#define mbedtls_fprintf fprintf
#define mbedtls_printf printf
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
#endif /* MBEDTLS_PLATFORM_C */
#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) || \
!defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
!defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C) || \
!defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
static void my_debug( void *ctx, int level,
const char *file, int line,
const char *str )
{
((void) level);
mbedtls_fprintf( (FILE *) ctx, "%s:%04d: %s", file, line, str );
fflush( (FILE *) ctx );
}
int main( void )
{
int ret = 1, len;
int exit_code = MBEDTLS_EXIT_FAILURE;
mbedtls_net_context server_fd;
uint32_t flags;
unsigned char buf[1024];
const char *pers = "ssl_client1";
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt cacert;
#if defined(MBEDTLS_DEBUG_C)
mbedtls_debug_set_threshold( DEBUG_LEVEL );
#endif
/*
* 0. Initialize the RNG and the session data
*/
mbedtls_net_init( &server_fd );
mbedtls_ssl_init( &ssl );
mbedtls_ssl_config_init( &conf );
mbedtls_x509_crt_init( &cacert );
mbedtls_ctr_drbg_init( &ctr_drbg );
mbedtls_printf( "\n . Seeding the random number generator..." );
fflush( stdout );
mbedtls_entropy_init( &entropy );
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *) pers,
strlen( pers ) ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
goto exit;
}
mbedtls_printf( " ok\n" );
/*
* 0. Initialize certificates
*/
mbedtls_printf( " . Loading the CA root certificate ..." );
fflush( stdout );
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem,
mbedtls_test_cas_pem_len );
if( ret < 0 )
{
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
goto exit;
}
mbedtls_printf( " ok (%d skipped)\n", ret );
/*
* 1. Start the connection
*/
mbedtls_printf( " . Connecting to tcp/%s/%s...", SERVER_NAME, SERVER_PORT );
fflush( stdout );
if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME,
SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret );
goto exit;
}
mbedtls_printf( " ok\n" );
/*
* 2. Setup stuff
*/
mbedtls_printf( " . Setting up the SSL/TLS structure..." );
fflush( stdout );
if( ( ret = mbedtls_ssl_config_defaults( &conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
goto exit;
}
mbedtls_printf( " ok\n" );
/* OPTIONAL is not optimal for security,
* but makes interop easier in this simplified example */
mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret );
goto exit;
}
if( ( ret = mbedtls_ssl_set_hostname( &ssl, SERVER_NAME ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
goto exit;
}
mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
/*
* 4. Handshake
*/
mbedtls_printf( " . Performing the SSL/TLS handshake..." );
fflush( stdout );
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
{
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
goto exit;
}
}
mbedtls_printf( " ok\n" );
/*
* 5. Verify the server certificate
*/
mbedtls_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];
mbedtls_printf( " failed\n" );
mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags );
mbedtls_printf( "%s\n", vrfy_buf );
}
else
mbedtls_printf( " ok\n" );
/*
* 3. Write the GET request
*/
mbedtls_printf( " > Write to server:" );
fflush( stdout );
len = sprintf( (char *) buf, GET_REQUEST );
while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 )
{
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret );
goto exit;
}
}
len = ret;
mbedtls_printf( " %d bytes written\n\n%s", len, (char *) buf );
/*
* 7. Read the HTTP response
*/
mbedtls_printf( " < Read from server:" );
fflush( stdout );
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 )
{
mbedtls_printf( "failed\n ! mbedtls_ssl_read returned %d\n\n", ret );
break;
}
if( ret == 0 )
{
mbedtls_printf( "\n\nEOF\n\n" );
break;
}
len = ret;
mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
}
while( 1 );
mbedtls_ssl_close_notify( &ssl );
exit_code = MBEDTLS_EXIT_SUCCESS;
exit:
#ifdef MBEDTLS_ERROR_C
if( exit_code != MBEDTLS_EXIT_SUCCESS )
{
char error_buf[100];
// mbedtls_strerror( ret, error_buf, 100 );
mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf );
}
#endif
mbedtls_net_free( &server_fd );
mbedtls_x509_crt_free( &cacert );
mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
#if defined(_WIN32)
mbedtls_printf( " + Press Enter to exit this program.\n" );
fflush( stdout ); getchar();
#endif
return( exit_code );
}
#endif
Hi,
Yes, I complied the project and run it on my evb. It seems ok. I use MCUXpresso.
Can you give more detail about your problem?
Regards,
Jing
Jing Pan,
I changed post above.
Thank u for help!
Hi,
It seems you write a new main() by yourself. There is no lwip code, and even no borad initialize code. I guess you want to test mbedTLS only. You can test the projects in \boards\frdmk64f\mbedtls_examples.
Regards,
Jing
Yes, youre right!
I tested it, and used this examples.
I found that I cant use functions: `mbedtls_net_init()' `mbedtls_net_connect()' `mbedtls_net_recv()' etc from net_sockets.h.
I try build my client by using server example for k64f.
Maybe u have any simple example of mbedTLS client working on k64f? (only writting and/or reading messages)
Now my main():
int main(void)
{
struct netif fsl_netif0;
int ret;
ip4_addr_t fsl_netif0_ipaddr, fsl_netif0_netmask, fsl_netif0_gw;
ethernetif_config_t fsl_enet_config0 = {
.phyAddress = EXAMPLE_PHY_ADDRESS,
.clockName = EXAMPLE_CLOCK_NAME,
.macAddress = configMAC_ADDR,
};
SYSMPU_Type *base = SYSMPU;
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
/* Disable SYSMPU. */
base->CESR &= ~SYSMPU_CESR_VLD_MASK;
time_init();
#if FSL_FEATURE_SOC_LTC_COUNT
/* Initialize LTC driver.
* This enables clocking and resets the module to a known state. */
LTC_Init(LTC0);
#endif
{ /* Init RNG module.*/
#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0)
trng_config_t trngConfig;
TRNG_GetDefaultConfig(&trngConfig);
/* Set sample mode of the TRNG ring oscillator to Von Neumann, for better random data.*/
trngConfig.sampleMode = kTRNG_SampleModeVonNeumann;
/* Initialize TRNG */
TRNG_Init(TRNG0, &trngConfig);
#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0)
RNGA_Init(RNG);
RNGA_Seed(RNG, SIM->UIDL);
#endif
}
IP4_ADDR(&fsl_netif0_ipaddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3);
IP4_ADDR(&fsl_netif0_netmask, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3);
IP4_ADDR(&fsl_netif0_gw, configGW_ADDR0, configGW_ADDR1, configGW_ADDR2, configGW_ADDR3);
lwip_init();
netif_add(&fsl_netif0, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw,
&fsl_enet_config0, ethernetif0_init, ethernet_input);
netif_set_default(&fsl_netif0);
netif_set_up(&fsl_netif0);
/*
* mbedTLS - setup
*/
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
#if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_init(&cache);
#endif
mbedtls_x509_crt_init(&srvcert);
mbedtls_pk_init(&pkey);
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
#if defined(MBEDTLS_DEBUG_C)
mbedtls_debug_set_threshold(DEBUG_LEVEL);
#endif
/*
* 1. Load the certificates and private RSA key
*/
/*
* This demonstration program uses embedded test certificates.
* Instead, you may want to use mbedtls_x509_crt_parse_file() to read the
* server and CA certificates, as well as mbedtls_pk_parse_keyfile().
*/
ret = mbedtls_x509_crt_parse(&srvcert, (const unsigned char *)mbedtls_test_srv_crt, mbedtls_test_srv_crt_len);
if (ret != 0)
{
PRINTF(" failed\r\n ! mbedtls_x509_crt_parse returned %d\r\n\r\n", ret);
goto exit;
}
ret = mbedtls_x509_crt_parse(&srvcert, (const unsigned char *)mbedtls_test_cas_pem, mbedtls_test_cas_pem_len);
if (ret != 0)
{
PRINTF(" failed\r\n ! mbedtls_x509_crt_parse returned %d\r\n\r\n", ret);
goto exit;
}
ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *)mbedtls_test_srv_key, mbedtls_test_srv_key_len, NULL, 0);
if (ret != 0)
{
PRINTF(" failed\r\n ! mbedtls_pk_parse_key returned %d\r\n\r\n", ret);
goto exit;
}
/*
* 2. Seeding the random number generator
*/
if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)pers,
strlen(pers))) != 0)
{
PRINTF(" failed\r\n ! mbedtls_ctr_drbg_seed returned %d\r\n", ret);
goto exit;
}
/*
* 3. Setting up the SSL data.
*/
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\r\n", ret);
goto exit;
}
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
mbedtls_ssl_conf_dbg(&conf, my_debug, NULL);
#if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_conf_session_cache(&conf, &cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set);
#endif
mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL);
if ((ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey)) != 0)
{
PRINTF(" failed\r\n ! mbedtls_ssl_conf_own_cert returned %d\r\n\r\n", ret);
goto exit;
}
if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0)
{
PRINTF(" failed\r\n ! mbedtls_ssl_setup returned %d\r\n\r\n", ret);
goto exit;
}
printf("starting client https\n\r");
err_t connected;
while (1)
{
connected = httpd_mbedtls_client_init(&ssl);
while(connected == ERR_OK)
{
ethernetif_input(&fsl_netif0);
sys_check_timeouts();
}
if(connected != ERR_OK)
{
printf("not connected\n\r");
}
}
exit:
return -1;
}
function httpd_mbedtls_client_init();
err_t httpd_mbedtls_client_init(mbedtls_ssl_context *ssl)
{
struct tcp_pcb *pcb;
ip4_addr_t dest;
err_t err;
IP4_ADDR(&dest, 192, 168, 0, 102);
pcb = tcp_new();
err = tcp_connect(pcb, &dest, HTTPS_CLIENT_PORT, client_connected); //server port for incoming connection
if (err != ERR_OK)
{
printf("\n tcp_connect(): Errors on return value, returned value is %d\n", err);
}
else
{
printf("\n tcp_connect(): connected\n\r");
}
ssl_p = ssl;
return err;
}
And function client_connected:
static err_t client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
printf("client connected function \n\r");
unsigned char bufor[1024];
int ret = 1, len;
LWIP_UNUSED_ARG(arg);
if (err != ERR_OK)
{
printf("\nclient_connected(): err argument not set to ERR_OK, but is value is %d\n", err);
}
else
{
// if connected:
if( ( ret = mbedtls_ssl_set_hostname( &ssl, "Bony_x" ) ) != 0 )
{
printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
return -1;
}
mbedtls_ssl_set_bio(&ssl, &ssl_p, mbedtls_net_send, mbedtls_net_recv, NULL);
/* Start the TLS handshake */
printf("Starting the TLS handshake...\n");
do {
ret = mbedtls_ssl_handshake(&ssl);
} while(ret != 0 &&
(ret == MBEDTLS_ERR_SSL_WANT_READ ||
ret == MBEDTLS_ERR_SSL_WANT_WRITE));
if (ret < 0) {
printf("mbedtls_ssl_handshake() returned -0x%04X\n", -ret);
return ret;
}
printf("Successfully completed the TLS handshake\n");
}
return err;
}
Now I should to make functions "mbedtls_net_send" and "mbedtls_net_recv".
Looks ok?
Regards,
Bony