2021-01-05 12:15:26 +01:00
# include "https_client.h"
static const char * TAG = " https_client " ;
static const char * REQUEST = " GET " CONFIG_OTA_HTTPS_URL " HTTP/1.1 \r \n "
" Host: " CONFIG_OTA_HTTPS_SERVER_COMMON_NAME " \r \n "
" User-Agent: esp-idf/1.0 esp32 \r \n "
" Authorization: Basic " CONFIG_OTA_HTTPS_AUTH " \r \n "
" \r \n " ;
2021-01-06 23:04:05 +01:00
2021-01-05 12:15:26 +01:00
static HTTPS_Client_t sHTTPS_ClientConfig ;
https_client_ret_t https_clientInitEmbedTLS ( ) ;
https_client_ret_t https_clientConnectToServer ( ) ;
https_client_ret_t https_clientValidateServer ( ) ;
https_client_ret_t https_clientSendRequest ( ) ;
https_client_ret_t https_clientInitialize ( )
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
i32RetHTTPClient = https_clientInitEmbedTLS ( ) ;
if ( i32RetHTTPClient = = HTTPS_CLIENT_OK )
{
i32RetHTTPClient = https_clientConnectToServer ( ) ;
}
if ( i32RetHTTPClient = = HTTPS_CLIENT_OK )
{
i32RetHTTPClient = https_clientValidateServer ( ) ;
}
if ( i32RetHTTPClient = = HTTPS_CLIENT_OK )
{
i32RetHTTPClient = https_clientSendRequest ( ) ;
}
switch ( i32RetHTTPClient )
{
case HTTPS_CLIENT_ERROR_INIT_EMBEDTLS :
ESP_LOGE ( TAG , " Unable to initialize EmbedTLS " ) ;
i32RetHTTPClient = HTTPS_CLIENT_ERROR ;
break ;
case HTTPS_CLIENT_ERROR_INIT_CONNECT_TWO_SERVER :
ESP_LOGE ( TAG , " Unable to connect to server " ) ;
i32RetHTTPClient = HTTPS_CLIENT_ERROR ;
break ;
case HTTPS_CLIENT_ERROR_INIT_VALIDATE_SERVER :
ESP_LOGE ( TAG , " Unable to validate the server " ) ;
i32RetHTTPClient = HTTPS_CLIENT_ERROR ;
break ;
case HTTPS_CLIENT_ERROR_INIT_SEND_REQUEST :
ESP_LOGE ( TAG , " Unable to send request to server " ) ;
i32RetHTTPClient = HTTPS_CLIENT_ERROR ;
break ;
case HTTPS_CLIENT_OK :
ESP_LOGI ( TAG , " HTTPS Client successfully initialized " ) ;
i32RetHTTPClient = HTTPS_CLIENT_OK ;
break ;
default :
i32RetHTTPClient = HTTPS_CLIENT_ERROR ;
2021-01-09 17:41:40 +01:00
ESP_LOGE ( TAG , " Unknown error while init https client " ) ;
2021-01-05 12:15:26 +01:00
break ;
}
return i32RetHTTPClient ;
}
2021-01-07 23:10:36 +01:00
https_client_ret_t https_clientRetrieveData ( char * pu8Data , uint32_t * pu32DataLenght , uint32_t * pu32BytesRead )
2021-01-05 12:15:26 +01:00
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
int32_t i32RetRetrieveData = ESP_OK ;
bool bRetriveData = true ;
2021-01-09 17:41:40 +01:00
bzero ( pu8Data , * pu32DataLenght ) ;
2021-01-08 23:08:07 +01:00
* pu32BytesRead = 0U ;
2021-01-05 12:15:26 +01:00
while ( bRetriveData )
{
//Reading HTTP response
2021-01-08 23:08:07 +01:00
i32RetRetrieveData = mbedtls_ssl_read ( & sHTTPS_ClientConfig . ssl , ( unsigned char * ) ( pu8Data + ( * pu32BytesRead ) ) , ( ( * pu32DataLenght ) - ( * pu32BytesRead ) ) ) ;
2021-01-05 12:15:26 +01:00
if ( i32RetRetrieveData > 0 )
{
//Data received
* pu32BytesRead = * pu32BytesRead + i32RetRetrieveData ;
if ( * pu32DataLenght > 0 )
{
//buffer not full yet --> read some more
bRetriveData = true ;
}
else
{
//buffer full --> stop reading
bRetriveData = false ;
}
}
if ( i32RetRetrieveData = = 0 )
{
//all data read --> stop reading
bRetriveData = false ;
2021-01-08 20:12:03 +01:00
pu32BytesRead = 0 ;
2021-01-05 12:15:26 +01:00
}
if ( i32RetRetrieveData = = MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
{
//connection is going to be closed
i32RetHTTPClient = HTTPS_CLIENT_ERROR ;
bRetriveData = false ;
}
}
return i32RetHTTPClient ;
}
https_client_ret_t https_clientDeinitialize ( )
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
2021-01-09 17:41:40 +01:00
i32RetHTTPClient = mbedtls_ssl_close_notify ( & sHTTPS_ClientConfig . ssl ) ; //close session
2021-01-05 12:15:26 +01:00
if ( i32RetHTTPClient ! = ESP_OK )
{
ESP_LOGE ( TAG , " mbedtls_ssl_close_notify returned 0x%x " , i32RetHTTPClient ) ;
}
2021-01-09 17:41:40 +01:00
mbedtls_ssl_session_reset ( & sHTTPS_ClientConfig . ssl ) ; //reset embedssl
mbedtls_net_free ( & sHTTPS_ClientConfig . server_fd ) ; //free ram
2021-01-05 12:15:26 +01:00
return i32RetHTTPClient ;
}
https_client_ret_t https_clientInitEmbedTLS ( ) {
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
int32_t i32RetEmbedTLS = ESP_OK ;
mbedtls_ssl_init ( & sHTTPS_ClientConfig . ssl ) ;
mbedtls_x509_crt_init ( & sHTTPS_ClientConfig . cacert ) ;
mbedtls_ctr_drbg_init ( & sHTTPS_ClientConfig . ctr_drbg ) ;
mbedtls_ssl_config_init ( & sHTTPS_ClientConfig . conf ) ;
mbedtls_entropy_init ( & sHTTPS_ClientConfig . entropy ) ;
i32RetEmbedTLS = mbedtls_ctr_drbg_seed ( & sHTTPS_ClientConfig . ctr_drbg , mbedtls_entropy_func , & sHTTPS_ClientConfig . entropy , NULL , 0 ) ;
if ( i32RetEmbedTLS ! = ESP_OK )
{
ESP_LOGE ( TAG , " mbedtls_ctr_drbg_seed returned %d " , i32RetEmbedTLS ) ;
}
if ( i32RetEmbedTLS = = ESP_OK )
{
//Attaching the certificate bundle
i32RetEmbedTLS = esp_crt_bundle_attach ( & sHTTPS_ClientConfig . conf ) ;
if ( i32RetEmbedTLS ! = ESP_OK )
{
ESP_LOGE ( TAG , " esp_crt_bundle_attach returned 0x%x \n \n " , i32RetEmbedTLS ) ;
}
}
if ( i32RetEmbedTLS = = ESP_OK )
{
//Setting hostname for TLS session.
i32RetEmbedTLS = mbedtls_ssl_set_hostname ( & sHTTPS_ClientConfig . ssl , CONFIG_OTA_HTTPS_SERVER_COMMON_NAME ) ;
// Hostname set here should match CN in server certificate
if ( i32RetEmbedTLS ! = ESP_OK )
{
ESP_LOGE ( TAG , " mbedtls_ssl_set_hostname returned 0x%x " , i32RetEmbedTLS ) ;
}
}
if ( i32RetEmbedTLS = = ESP_OK )
{
//Setting up the SSL/TLS structure
i32RetEmbedTLS = mbedtls_ssl_config_defaults ( & sHTTPS_ClientConfig . conf ,
MBEDTLS_SSL_IS_CLIENT ,
MBEDTLS_SSL_TRANSPORT_STREAM ,
MBEDTLS_SSL_PRESET_DEFAULT ) ;
if ( i32RetEmbedTLS ! = ESP_OK )
{
ESP_LOGE ( TAG , " mbedtls_ssl_config_defaults returned %d " , i32RetEmbedTLS ) ;
}
}
if ( i32RetEmbedTLS = = ESP_OK )
{
mbedtls_ssl_conf_authmode ( & sHTTPS_ClientConfig . conf , MBEDTLS_SSL_VERIFY_REQUIRED ) ;
mbedtls_ssl_conf_ca_chain ( & sHTTPS_ClientConfig . conf , & sHTTPS_ClientConfig . cacert , NULL ) ;
mbedtls_ssl_conf_rng ( & sHTTPS_ClientConfig . conf , mbedtls_ctr_drbg_random , & sHTTPS_ClientConfig . ctr_drbg ) ;
i32RetEmbedTLS = mbedtls_ssl_setup ( & sHTTPS_ClientConfig . ssl , & sHTTPS_ClientConfig . conf ) ;
if ( i32RetEmbedTLS ! = ESP_OK )
{
ESP_LOGE ( TAG , " mbedtls_ssl_setup returned -0x%x \n \n " , i32RetEmbedTLS ) ;
}
}
if ( i32RetEmbedTLS = = ESP_OK )
{
mbedtls_net_init ( & sHTTPS_ClientConfig . server_fd ) ;
}
if ( i32RetEmbedTLS ! = ESP_OK )
{
i32RetHTTPClient = HTTPS_CLIENT_ERROR_INIT_EMBEDTLS ;
}
return i32RetHTTPClient ;
}
https_client_ret_t https_clientConnectToServer ( )
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
int32_t i32RetServerConnect = ESP_OK ;
//Connecting to server
i32RetServerConnect = mbedtls_net_connect ( & sHTTPS_ClientConfig . server_fd , CONFIG_OTA_HTTPS_SERVER_COMMON_NAME , CONFIG_OTA_HTTPS_SERVER_PORT , MBEDTLS_NET_PROTO_TCP ) ;
if ( i32RetServerConnect ! = ESP_OK )
{
ESP_LOGE ( TAG , " mbedtls_net_connect returned %x " , i32RetServerConnect ) ;
}
if ( i32RetServerConnect = = ESP_OK )
{
mbedtls_ssl_set_bio ( & sHTTPS_ClientConfig . ssl , & sHTTPS_ClientConfig . server_fd , mbedtls_net_send , mbedtls_net_recv , NULL ) ;
//Performing the SSL/TLS handshake
while ( ( i32RetServerConnect = mbedtls_ssl_handshake ( & sHTTPS_ClientConfig . ssl ) ) ! = 0 )
{
if ( ( i32RetServerConnect ! = MBEDTLS_ERR_SSL_WANT_READ ) & & ( i32RetServerConnect ! = MBEDTLS_ERR_SSL_WANT_WRITE ) )
{
ESP_LOGE ( TAG , " mbedtls_ssl_handshake returned 0x%x " , i32RetServerConnect ) ;
}
}
}
if ( i32RetServerConnect ! = ESP_OK )
{
i32RetHTTPClient = HTTPS_CLIENT_ERROR_INIT_CONNECT_TWO_SERVER ;
}
return i32RetHTTPClient ;
}
https_client_ret_t https_clientValidateServer ( )
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
int32_t i32RetValidateServer = ESP_OK ;
//Verifying peer X.509 certificate
if ( ( i32RetValidateServer = mbedtls_ssl_get_verify_result ( & sHTTPS_ClientConfig . ssl ) ) ! = 0 )
{
ESP_LOGE ( TAG , " Failed to verify peer certificate! " ) ;
}
if ( i32RetValidateServer ! = ESP_OK )
{
i32RetHTTPClient = HTTPS_CLIENT_ERROR_INIT_VALIDATE_SERVER ;
}
return i32RetHTTPClient ;
}
https_client_ret_t https_clientSendRequest ( )
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
int32_t i32RetSendRequest = ESP_OK ;
uint32_t u32WrittenBytes = 0 ;
2021-01-09 17:41:40 +01:00
bool bWrite = true ; //flag to stop loop
2021-01-05 12:15:26 +01:00
//Writing HTTP request
while ( ( u32WrittenBytes < strlen ( REQUEST ) ) & & bWrite )
{
i32RetSendRequest = mbedtls_ssl_write ( & sHTTPS_ClientConfig . ssl ,
( const unsigned char * ) REQUEST + u32WrittenBytes ,
strlen ( REQUEST ) - u32WrittenBytes ) ;
if ( i32RetSendRequest > = 0 )
{
//bytes written
u32WrittenBytes + = i32RetSendRequest ;
} else if ( i32RetSendRequest ! = MBEDTLS_ERR_SSL_WANT_WRITE & & i32RetSendRequest ! = MBEDTLS_ERR_SSL_WANT_READ ) {
ESP_LOGE ( TAG , " mbedtls_ssl_write returned 0x%x " , i32RetSendRequest ) ;
bWrite = false ;
}
}
if ( bWrite = = false )
{
i32RetHTTPClient = HTTPS_CLIENT_ERROR_INIT_SEND_REQUEST ;
}
return i32RetHTTPClient ;
}