Adapting the ssl Function

Change-Id: Id545424443408fd91c793aba605aebd0a2fb84e0
diff --git a/mbtk/libmbtk_lib/net/mbtk_mbedtls.c b/mbtk/libmbtk_lib/net/mbtk_mbedtls.c
new file mode 100755
index 0000000..aaa638a
--- /dev/null
+++ b/mbtk/libmbtk_lib/net/mbtk_mbedtls.c
@@ -0,0 +1,406 @@
+/*-----------------------------------------------------------------------------------------------*/

+/**

+  @file mbtk_mbedtls.c

+  @brief MBEDTLS API

+*/

+/*-----------------------------------------------------------------------------------------------*/

+

+/*-------------------------------------------------------------------------------------------------

+  Copyright (c) 2024 mobiletek Wireless Solution, Co., Ltd. All Rights Reserved.

+  mobiletek Wireless Solution Proprietary and Confidential.

+-------------------------------------------------------------------------------------------------*/

+

+/*-------------------------------------------------------------------------------------------------

+  EDIT HISTORY

+  This section contains comments describing changes made to the file.

+  Notice that changes are listed in reverse chronological order.

+  $Header: $

+  when       who          what, where, why

+  --------   ---------    -----------------------------------------------------------------

+  20250409    yq.wang      Created .

+-------------------------------------------------------------------------------------------------*/

+#ifdef MBTK_MBEDTLS_V3_6_2_SUPPORT

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <unistd.h>

+

+#include "mbtk_log.h"

+#include "mbtk_mbedtls.h"

+

+#define MBTK_SSL_PERS_STR_DEFAULT "mbtk_ssl"

+#define MBTK_SSL_INFO_FD_DEFAULT -1

+#define MBTK_SSL_BUFFER_SIZE_1024 1024

+#define MBTK_SSL_BUFFER_SIZE_128 128

+

+static mbtk_mbedtls_ssl_result_e mbtk_mbedtls_ssl_info_free(mbtk_mbedtls_ssl_info_s *ssl_info)

+{

+    if(NULL == ssl_info)

+    {

+        LOGE("[%s] ssl_info [NULL]", __func__);

+        return MBTK_MBEDTLS_SSL_RESULT_FAIL;

+    }

+

+    if(NULL != ssl_info->entropy)

+    {

+        free(ssl_info->entropy);

+        ssl_info->entropy = NULL;

+    }

+

+    if(NULL != ssl_info->ctr_drbg)

+    {

+        free(ssl_info->ctr_drbg);

+        ssl_info->ctr_drbg = NULL;

+    }

+

+    if(NULL != ssl_info->ssl)

+    {

+        free(ssl_info->ssl);

+        ssl_info->ssl = NULL;

+    }

+

+    if(NULL != ssl_info->conf)

+    {

+        free(ssl_info->conf);

+        ssl_info->conf = NULL;

+    }

+

+    if(NULL != ssl_info->cacert)

+    {

+        free(ssl_info->cacert);

+        ssl_info->cacert = NULL;

+    }

+

+    if(NULL != ssl_info->clientcert)

+    {

+        free(ssl_info->clientcert);

+        ssl_info->clientcert = NULL;

+    }

+

+    if(NULL != ssl_info->clientkey)

+    {

+        free(ssl_info->clientkey);

+        ssl_info->clientkey = NULL;

+    }

+

+    return MBTK_MBEDTLS_SSL_RESULT_SUCCESS;

+}

+

+static mbtk_mbedtls_ssl_result_e mbtk_mbedtls_ssl_info_malloc(mbtk_mbedtls_ssl_info_s *ssl_info)

+{

+    if(NULL == ssl_info)

+    {

+        LOGE("[%s] ssl_info [NULL]", __func__);

+        return MBTK_MBEDTLS_SSL_RESULT_FAIL;

+    }

+    

+    ssl_info->entropy = (mbedtls_entropy_context *)malloc(sizeof(mbedtls_entropy_context));

+    if(NULL == ssl_info->entropy)

+    {

+        LOGE("[%s] entropy malloc() fail", __func__);

+        goto free_error;

+    }

+

+    ssl_info->ctr_drbg = (mbedtls_ctr_drbg_context *)malloc(sizeof(mbedtls_ctr_drbg_context));

+    if(NULL == ssl_info->ctr_drbg)

+    {

+        LOGE("[%s] ctr_drbg malloc() fail", __func__);

+        goto free_error;

+    }

+    

+    ssl_info->ssl = (mbedtls_ssl_context *)malloc(sizeof(mbedtls_ssl_context));

+    if(NULL == ssl_info->ssl)

+    {

+        LOGE("[%s] ssl malloc() fail", __func__);

+        goto free_error;

+    }

+    

+    ssl_info->conf = (mbedtls_ssl_config *)malloc(sizeof(mbedtls_ssl_config));

+    if(NULL == ssl_info->conf)

+    {

+        LOGE("[%s] conf malloc() fail", __func__);

+        goto free_error;

+    }

+    

+    ssl_info->cacert = (mbedtls_x509_crt *)malloc(sizeof(mbedtls_x509_crt));

+    if(NULL == ssl_info->cacert)

+    {

+        LOGE("[%s] cacert malloc() fail", __func__);

+        goto free_error;

+    }

+    

+    ssl_info->clientcert = (mbedtls_x509_crt *)malloc(sizeof(mbedtls_x509_crt));

+    if(NULL == ssl_info->clientcert)

+    {

+        LOGE("[%s] clientcert malloc() fail", __func__);

+        goto free_error;

+    }

+    

+    ssl_info->clientkey = (mbedtls_pk_context *)malloc(sizeof(mbedtls_pk_context));

+    if(NULL == ssl_info->clientkey)

+    {

+        LOGE("[%s] clientkey malloc() fail", __func__);

+        goto free_error;

+    }

+    

+    return MBTK_MBEDTLS_SSL_RESULT_SUCCESS;

+free_error:

+    mbtk_mbedtls_ssl_info_free(ssl_info);

+    

+    return MBTK_MBEDTLS_SSL_RESULT_FAIL;

+}

+

+mbtk_mbedtls_ssl_result_e mbtk_mbedtls_ssl_options_default(mbtk_mbedtls_ssl_options_s *opt)

+{

+    if(NULL == opt)

+    {

+        LOGE("[%s] opt [NULL]", __func__);

+        return MBTK_MBEDTLS_SSL_RESULT_FAIL;

+    }

+

+    const mbedtls_x509_crt_profile mbtk_profile = mbedtls_x509_crt_profile_default;

+

+    opt->load_cert = false;

+    opt->ca_file = NULL;

+    opt->crt_file = NULL;

+    opt->key_file = NULL;

+    opt->pers_str = (unsigned char*)MBTK_SSL_PERS_STR_DEFAULT;

+    opt->pers_str_size = strlen((const char*)opt->pers_str);

+    opt->type = MBTK_MBEDTLS_SSL_IS_CLIENT;

+    opt->transprot = MBTK_MBEDTLS_SSL_TRANSPROT_STREAM;

+    opt->preset = MBTK_MBEDTLS_SSL_PRESET_DEFAULT;

+    opt->auth_mode = MBTK_MBEDTLS_SSL_VERIFY_OPTIONAL;

+    opt->renegotiation = MBTK_MBEDTLS_SSL_RENEGOTIATION_DISABLED;

+    opt->allow_legacy = MBTK_MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION;

+    opt->min_version = MBTK_MBEDTLS_SSL_MINOR_VERSION_3;

+    opt->max_version = MBTK_MBEDTLS_SSL_MINOR_VERSION_4;   

+    opt->allowed_mds = mbtk_profile.allowed_mds;

+    

+    return MBTK_MBEDTLS_SSL_RESULT_SUCCESS;

+}

+

+int mbtk_mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )

+{

+    return mbedtls_ssl_write(ssl, buf, len);

+}

+

+int mbtk_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )

+{

+    return mbedtls_ssl_read(ssl, buf, len);

+}

+

+mbtk_mbedtls_ssl_result_e mbtk_mbedtls_ssl_init(int fd , mbtk_mbedtls_ssl_options_s *opt, mbtk_mbedtls_ssl_info_s* inter_info)

+{

+    int ret = -1;

+    uint32_t flags = 0;

+    char verify_err[MBTK_SSL_BUFFER_SIZE_1024 + 1] = {0};

+    char cert_buff[MBTK_SSL_BUFFER_SIZE_1024 + 1] = {0};

+    mbtk_mbedtls_ssl_options_s temp_opt = {0};

+    mbtk_mbedtls_ssl_info_s temp_ssl_info = {0};

+    mbedtls_x509_crt_profile mbtk_profile = mbedtls_x509_crt_profile_default;

+    

+    if(NULL == inter_info)

+    {

+        LOGE("[%s] inter_info [NULL]", __func__);

+        return MBTK_MBEDTLS_SSL_RESULT_FAIL;

+    }

+

+    if(NULL == opt)

+    {

+        ret = mbtk_mbedtls_ssl_options_default(&temp_opt);

+    }

+    else

+    {

+        memset(&temp_opt, 0x00, sizeof(mbtk_mbedtls_ssl_options_s));

+        memcpy(&temp_opt, opt, sizeof(mbtk_mbedtls_ssl_options_s));

+    }

+

+    memset(&temp_ssl_info, 0x00, sizeof(mbtk_mbedtls_ssl_info_s));

+    ret = mbtk_mbedtls_ssl_info_malloc(&temp_ssl_info);

+    if(ret != 0)

+    {

+        LOGE("[%s] mbtk_mbedtls_ssl_info_malloc() fail", __func__);

+        return MBTK_MBEDTLS_SSL_RESULT_FAIL;

+    }

+

+    mbedtls_ctr_drbg_init(temp_ssl_info.ctr_drbg);

+    mbedtls_entropy_init(temp_ssl_info.entropy);

+    mbedtls_ssl_init(temp_ssl_info.ssl);

+    mbedtls_ssl_config_init(temp_ssl_info.conf);

+    mbedtls_x509_crt_init(temp_ssl_info.cacert);

+    mbedtls_x509_crt_init(temp_ssl_info.clientcert);

+    mbedtls_pk_init(temp_ssl_info.clientkey);

+

+    //1.Initialize the function for CTR_DRBG pseudorandom number generator

+    ret = mbedtls_ctr_drbg_seed(temp_ssl_info.ctr_drbg, mbedtls_entropy_func, temp_ssl_info.entropy, temp_opt.pers_str, temp_opt.pers_str_size);

+    if (ret != 0) 

+    {

+        LOGE("[%s] mbedtls_ctr_drbg_seed() fail.[-0x%x]", __func__, -ret);

+        goto error;

+    }

+

+    //2.Load certificate

+    if(temp_opt.load_cert)

+    {

+        if(NULL == temp_opt.ca_file || NULL == temp_opt.crt_file || NULL == temp_opt.key_file)

+        {

+            LOGE("[%s] file [NULL]", __func__);

+            goto error;

+        }

+		

+        //2.1-Load root certificate

+        ret = mbedtls_x509_crt_parse_file(temp_ssl_info.cacert, temp_opt.ca_file);

+        if(ret != 0)

+        {

+            LOGE("[%s] mbedtls_x509_crt_parse_file() CA fail.[-0x%x]", __func__, -ret);

+            goto error;

+        }

+

+        //2.2-Load the client public key

+        ret = mbedtls_x509_crt_parse_file(temp_ssl_info.clientcert, temp_opt.crt_file);

+        if(ret != 0)

+        {

+            LOGE("[%s] mbedtls_x509_crt_parse_file() CRT fail.[-0x%x]", __func__, -ret);

+            goto error;

+        }

+

+        //2.3-Load the client private key

+        ret = mbedtls_pk_parse_keyfile(temp_ssl_info.clientkey, temp_opt.key_file, NULL, mbedtls_ctr_drbg_random, temp_ssl_info.ctr_drbg);

+        if(ret != 0)

+        {

+            LOGE("[%s] mbedtls_pk_parse_keyfile() KEY fail.[-0x%x]", __func__, -ret);

+            goto error;

+        }

+    }

+

+    LOGD("[%s] Configure the SSL/TLS context...", __func__);

+    //3.Configure the SSL/TLS context

+    ret = mbedtls_ssl_config_defaults(temp_ssl_info.conf, temp_opt.type, temp_opt.transprot, temp_opt.preset);

+    if(ret != 0) 

+    {

+        LOGE("[%s] mbedtls_ssl_config_defaults() fail.[-0x%x]", __func__, -ret);

+        goto error;

+    }

+

+    mbedtls_ssl_conf_authmode(temp_ssl_info.conf, temp_opt.auth_mode);

+    mbedtls_ssl_conf_ca_chain(temp_ssl_info.conf, temp_ssl_info.cacert, NULL);

+    if(temp_opt.load_cert)

+    {

+        ret = mbedtls_ssl_conf_own_cert(temp_ssl_info.conf, temp_ssl_info.clientcert, temp_ssl_info.clientkey);

+        if(ret != 0)

+        {

+            LOGE("[%s] mbedtls_ssl_conf_own_cert() fail.[-0x%x]", __func__, -ret);

+            goto error;

+        }

+    }

+

+    mbedtls_ssl_conf_rng(temp_ssl_info.conf, mbedtls_ctr_drbg_random, temp_ssl_info.ctr_drbg);

+    //mbedtls_ssl_conf_renegotiation(&conf, temp_opt.renegotiation);

+    mbedtls_ssl_conf_legacy_renegotiation(temp_ssl_info.conf, temp_opt.allow_legacy);

+    // TLS 1.2

+    mbedtls_ssl_conf_min_version(temp_ssl_info.conf, MBEDTLS_SSL_MAJOR_VERSION_3, temp_opt.min_version);

+    // TLS 1.3

+    mbedtls_ssl_conf_max_version(temp_ssl_info.conf, MBEDTLS_SSL_MAJOR_VERSION_3, temp_opt.max_version);

+

+    mbtk_profile.allowed_mds = temp_opt.allowed_mds;

+    mbedtls_ssl_conf_cert_profile(temp_ssl_info.conf, &mbtk_profile);

+    

+    //4.Binding SSL configuration

+    ret = mbedtls_ssl_setup(temp_ssl_info.ssl, temp_ssl_info.conf);

+    if (ret != 0)

+    {

+        LOGE("[%s] mbedtls_ssl_setup() fail.[-0x%x]", __func__, -ret);

+        goto error;

+    }

+   

+    mbedtls_ssl_set_bio(temp_ssl_info.ssl, &fd, mbedtls_net_send, mbedtls_net_recv, NULL);

+

+    LOGD("[%s] Performing the SSL/TLS handshake...", __func__);

+    //5.Shake hands  

+    while((ret = mbedtls_ssl_handshake(temp_ssl_info.ssl)) != 0)

+    {

+        if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)

+        {

+            LOGE("[%s] mbedtls_ssl_handshake() fail.[-0x%x]", __func__, -ret);

+            goto error;

+        }

+    }

+

+    LOGD("[%s] Handshake ok: Protocol[%s], Ciphersuite[%s]", __func__, mbedtls_ssl_get_version(temp_ssl_info.ssl), mbedtls_ssl_get_ciphersuite(temp_ssl_info.ssl));

+    //6.Verification certificate

+    flags = mbedtls_ssl_get_verify_result(temp_ssl_info.ssl);

+    if(flags != 0)

+    {

+        memset(verify_err, 0x00, MBTK_SSL_BUFFER_SIZE_1024 + 1);

+        mbedtls_x509_crt_verify_info(verify_err, MBTK_SSL_BUFFER_SIZE_1024, "[mbedtls_ssl_get_verify_result] ", flags);

+        LOGD("%s", verify_err);

+        if(temp_opt.auth_mode == MBTK_MBEDTLS_SSL_VERIFY_REQUIRED)

+        {

+            LOGE("[%s] mbedtls_ssl_get_verify_result() fail", __func__);

+            goto error;

+        }

+    }

+

+    if(mbedtls_ssl_get_peer_cert(temp_ssl_info.ssl) != NULL)

+    {

+        LOGD("[%s] Peer certificate information", __func__);

+        memset(cert_buff, 0x00, MBTK_SSL_BUFFER_SIZE_1024 + 1);

+        mbedtls_x509_crt_info(cert_buff, MBTK_SSL_BUFFER_SIZE_1024, "[mbedtls_ssl_get_verify_result] ", mbedtls_ssl_get_peer_cert(temp_ssl_info.ssl));

+        LOGD("%s", cert_buff);

+    }

+    

+    temp_ssl_info.fd = fd;

+    memcpy(inter_info, &temp_ssl_info, sizeof(mbtk_mbedtls_ssl_info_s));

+    

+    return MBTK_MBEDTLS_SSL_RESULT_SUCCESS;

+error:

+    mbedtls_ssl_close_notify(temp_ssl_info.ssl);

+    mbedtls_ssl_free(temp_ssl_info.ssl);

+    mbedtls_ssl_config_free(temp_ssl_info.conf);

+    mbedtls_ctr_drbg_free(temp_ssl_info.ctr_drbg);

+    mbedtls_entropy_free(temp_ssl_info.entropy);  

+    mbedtls_pk_free(temp_ssl_info.clientkey);

+    mbedtls_x509_crt_free(temp_ssl_info.clientcert);

+    mbedtls_x509_crt_free(temp_ssl_info.cacert);

+

+    mbtk_mbedtls_ssl_info_free(&temp_ssl_info);

+    return MBTK_MBEDTLS_SSL_RESULT_FAIL;

+}

+

+mbtk_mbedtls_ssl_result_e mbtk_mbedtls_ssl_deinit(mbtk_mbedtls_ssl_info_s* inter_info)

+{

+    if(NULL == inter_info)

+    {

+        LOGE("[%s] inter_info [NULL]", __func__);

+        return MBTK_MBEDTLS_SSL_RESULT_FAIL;

+    }

+

+    int ret = -1;

+    char error_buf[MBTK_SSL_BUFFER_SIZE_128 + 1] = {0};

+    

+    do {

+        ret = mbedtls_ssl_close_notify(inter_info->ssl);

+    } while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE);

+

+    if(ret != 0)

+    {

+        memset(error_buf, 0x00, MBTK_SSL_BUFFER_SIZE_128 + 1);

+        mbedtls_strerror(ret, error_buf, MBTK_SSL_BUFFER_SIZE_128);

+        LOGE("[%s] mbedtls_ssl_close_notify() fail.[%s]", __func__, error_buf);

+    }

+

+    mbedtls_ssl_close_notify(inter_info->ssl);

+    mbedtls_ssl_free(inter_info->ssl);

+    mbedtls_ssl_config_free(inter_info->conf);

+    mbedtls_ctr_drbg_free(inter_info->ctr_drbg);

+    mbedtls_entropy_free(inter_info->entropy);  

+    mbedtls_pk_free(inter_info->clientkey);

+    mbedtls_x509_crt_free(inter_info->clientcert);

+    mbedtls_x509_crt_free(inter_info->cacert);

+    inter_info->fd = MBTK_SSL_INFO_FD_DEFAULT;

+

+    mbtk_mbedtls_ssl_info_free(inter_info);

+    return MBTK_MBEDTLS_SSL_RESULT_SUCCESS;

+}

+

+#endif