2021-01-17 23:47:59 +01:00
# include "HTTPS_client.h"
2021-01-16 00:23:02 +01:00
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 " ;
static HTTPS_Client_t sHTTPS_ClientConfig ;
https_client_ret_t https_clientInitEmbedTLS ( ) ;
2021-01-18 19:03:32 +01:00
https_client_ret_t errHTTPSClientConnectToServer ( ) ;
https_client_ret_t errHTTPSClientValidateServer ( ) ;
https_client_ret_t errHTTPSClientSendRequest ( ) ;
2021-01-16 00:23:02 +01:00
2021-01-18 19:03:32 +01:00
https_client_ret_t errHTTPSClientInitialize ( )
2021-01-16 00:23:02 +01:00
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
i32RetHTTPClient = https_clientInitEmbedTLS ( ) ;
2021-01-18 17:38:08 +01:00
if ( i32RetHTTPClient = = HTTPS_CLIENT_ERROR_INIT_EMBEDTLS )
2021-01-17 23:27:01 +01:00
{
ESP_LOGE ( TAG , " Unable to initialize EmbedTLS " ) ;
i32RetHTTPClient = HTTPS_CLIENT_ERROR ;
}
2021-01-16 00:23:02 +01:00
return i32RetHTTPClient ;
}
2021-01-18 19:03:32 +01:00
https_client_ret_t errHTTPSClientRetrieveData ( char * pu8Data , uint32_t * pu32DataLenght , uint32_t * pu32BytesRead )
2021-01-16 00:23:02 +01:00
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
int32_t i32RetRetrieveData = ESP_OK ;
bool bRetriveData = true ;
bzero ( pu8Data , * pu32DataLenght ) ;
* pu32BytesRead = 0U ;
while ( bRetriveData )
{
2021-01-18 17:38:08 +01:00
mbedtls_ssl_conf_read_timeout ( & sHTTPS_ClientConfig . conf , HTTPS_READ_TIMEOUT ) ; //set timeout
2021-01-17 23:27:01 +01:00
//Reading HTTP response
i32RetRetrieveData = mbedtls_ssl_read ( & sHTTPS_ClientConfig . ssl , ( unsigned char * ) ( pu8Data + ( * pu32BytesRead ) ) , ( ( * pu32DataLenght ) - ( * pu32BytesRead ) ) ) ;
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 ;
pu32BytesRead = 0 ;
}
2021-01-18 17:38:08 +01:00
if ( i32RetRetrieveData = = MBEDTLS_ERR_SSL_TIMEOUT )
{
//timeout --> stop reading
bRetriveData = false ;
}
2021-01-17 23:27:01 +01:00
if ( i32RetRetrieveData = = MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
{
//connection is going to be closed
i32RetHTTPClient = HTTPS_CLIENT_ERROR ;
bRetriveData = false ;
}
2021-01-16 00:23:02 +01:00
}
return i32RetHTTPClient ;
}
2021-01-18 19:03:32 +01:00
https_client_ret_t errHTTPSClientReset ( )
2021-01-18 12:49:52 +01:00
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
2021-01-16 00:23:02 +01:00
i32RetHTTPClient = mbedtls_ssl_close_notify ( & sHTTPS_ClientConfig . ssl ) ; //close session
if ( i32RetHTTPClient ! = ESP_OK )
2021-01-17 23:27:01 +01:00
{
ESP_LOGE ( TAG , " mbedtls_ssl_close_notify returned 0x%x " , i32RetHTTPClient ) ;
}
2021-01-16 00:23:02 +01:00
mbedtls_ssl_session_reset ( & sHTTPS_ClientConfig . ssl ) ; //reset embedssl
mbedtls_net_free ( & sHTTPS_ClientConfig . server_fd ) ; //free ram
return i32RetHTTPClient ;
}
2021-01-17 23:27:01 +01:00
https_client_ret_t https_clientInitEmbedTLS ( )
{
2021-01-16 00:23:02 +01:00
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
int32_t i32RetEmbedTLS = ESP_OK ;
2021-01-18 12:49:52 +01:00
static bool bAlreadySetup = false ;
2021-01-16 00:23:02 +01:00
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 )
2021-01-17 23:27:01 +01:00
{
ESP_LOGE ( TAG , " mbedtls_ctr_drbg_seed returned %d " , i32RetEmbedTLS ) ;
}
2021-01-16 00:23:02 +01:00
if ( i32RetEmbedTLS = = ESP_OK )
{
2021-01-17 23:27:01 +01:00
//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 ) ;
}
2021-01-16 00:23:02 +01:00
}
if ( i32RetEmbedTLS = = ESP_OK )
{
2021-01-17 23:27:01 +01:00
//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 ) ;
}
2021-01-16 00:23:02 +01:00
}
if ( i32RetEmbedTLS = = ESP_OK )
{
2021-01-17 23:27:01 +01:00
//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 ) ;
}
2021-01-16 00:23:02 +01:00
}
if ( i32RetEmbedTLS = = ESP_OK )
{
2021-01-17 23:27:01 +01:00
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 ) ;
2021-01-18 12:49:52 +01:00
if ( bAlreadySetup = = false ) //check if mbedtls_ssl_setup was called before
2021-01-17 23:27:01 +01:00
{
2021-01-18 12:49:52 +01:00
i32RetEmbedTLS = mbedtls_ssl_setup ( & sHTTPS_ClientConfig . ssl , & sHTTPS_ClientConfig . conf ) ; //call this only once
if ( i32RetEmbedTLS ! = ESP_OK )
{
ESP_LOGE ( TAG , " mbedtls_ssl_setup returned 0x%x \n \n " , i32RetEmbedTLS ) ;
// uint8_t buffer[20];
//mbedtls_strerror(i32RetEmbedTLS, buffer, 20);
//ESP_LOGE(TAG, "%s", buffer);
}
else
{
bAlreadySetup = true ;
}
2021-01-17 23:27:01 +01:00
}
2021-01-18 12:49:52 +01:00
2021-01-16 00:23:02 +01:00
}
if ( i32RetEmbedTLS = = ESP_OK )
2021-01-17 23:27:01 +01:00
{
mbedtls_net_init ( & sHTTPS_ClientConfig . server_fd ) ;
}
2021-01-16 00:23:02 +01:00
if ( i32RetEmbedTLS ! = ESP_OK )
2021-01-17 23:27:01 +01:00
{
i32RetHTTPClient = HTTPS_CLIENT_ERROR_INIT_EMBEDTLS ;
}
2021-01-16 00:23:02 +01:00
return i32RetHTTPClient ;
}
2021-01-18 19:03:32 +01:00
https_client_ret_t errHTTPSClientConnectToServer ( )
2021-01-16 00:23:02 +01:00
{
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 )
2021-01-17 23:27:01 +01:00
{
ESP_LOGE ( TAG , " mbedtls_net_connect returned %x " , i32RetServerConnect ) ;
}
2021-01-16 00:23:02 +01:00
if ( i32RetServerConnect = = ESP_OK )
{
2021-01-18 17:38:08 +01:00
mbedtls_ssl_set_bio ( & sHTTPS_ClientConfig . ssl , & sHTTPS_ClientConfig . server_fd , mbedtls_net_send , mbedtls_net_recv , mbedtls_net_recv_timeout ) ;
2021-01-17 23:27:01 +01:00
//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 ) ;
}
}
2021-01-16 00:23:02 +01:00
}
if ( i32RetServerConnect ! = ESP_OK )
2021-01-17 23:27:01 +01:00
{
i32RetHTTPClient = HTTPS_CLIENT_ERROR_INIT_CONNECT_TWO_SERVER ;
}
2021-01-16 00:23:02 +01:00
return i32RetHTTPClient ;
}
2021-01-18 19:03:32 +01:00
https_client_ret_t errHTTPSClientValidateServer ( )
2021-01-16 00:23:02 +01:00
{
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 )
2021-01-17 23:27:01 +01:00
{
ESP_LOGE ( TAG , " Failed to verify peer certificate! " ) ;
}
2021-01-16 00:23:02 +01:00
if ( i32RetValidateServer ! = ESP_OK )
2021-01-17 23:27:01 +01:00
{
i32RetHTTPClient = HTTPS_CLIENT_ERROR_INIT_VALIDATE_SERVER ;
}
2021-01-16 00:23:02 +01:00
return i32RetHTTPClient ;
}
2021-01-18 19:03:32 +01:00
https_client_ret_t errHTTPSClientSendRequest ( )
2021-01-16 00:23:02 +01:00
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK ;
int32_t i32RetSendRequest = ESP_OK ;
uint32_t u32WrittenBytes = 0 ;
bool bWrite = true ; //flag to stop loop
//Writing HTTP request
while ( ( u32WrittenBytes < strlen ( REQUEST ) ) & & bWrite )
{
2021-01-17 23:27:01 +01:00
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 ;
}
2021-01-16 00:23:02 +01:00
}
if ( bWrite = = false )
2021-01-17 23:27:01 +01:00
{
i32RetHTTPClient = HTTPS_CLIENT_ERROR_INIT_SEND_REQUEST ;
}
2021-01-16 00:23:02 +01:00
return i32RetHTTPClient ;
}