From: Anurag Kar Date: Mon, 15 Apr 2019 13:06:09 +0000 (+0530) Subject: Protocomm : Added new APIs for opening and closing secure sessions X-Git-Tag: v4.0-beta1~291^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=86e9acc2c997d2cd188f4edce1d6e3447c182c41;p=esp-idf Protocomm : Added new APIs for opening and closing secure sessions New APIs: * protocomm_open_session() * protocomm_close_session() This allows external applications using protocomm to manually create and close sessions. These internally call the new_transport_session() and close_transport_session() APIs implemented by the security scheme in use. Updated unit tests with usage of new APIs --- diff --git a/components/protocomm/include/common/protocomm.h b/components/protocomm/include/common/protocomm.h index 239d71390b..cb11a0b132 100644 --- a/components/protocomm/include/common/protocomm.h +++ b/components/protocomm/include/common/protocomm.h @@ -114,6 +114,39 @@ esp_err_t protocomm_add_endpoint(protocomm_t *pc, const char *ep_name, */ esp_err_t protocomm_remove_endpoint(protocomm_t *pc, const char *ep_name); +/** + * @brief Allocates internal resources for new transport session + * + * @note + * - An endpoint must be bound to a valid protocomm instance, + * created using `protocomm_new()`. + * + * @param[in] pc Pointer to the protocomm instance + * @param[in] session_id Unique ID for a communication session + * + * @return + * - ESP_OK : Request handled successfully + * - ESP_ERR_NO_MEM : Error allocating internal resource + * - ESP_ERR_INVALID_ARG : Null instance/name arguments + */ +esp_err_t protocomm_open_session(protocomm_t *pc, uint32_t session_id); + +/** + * @brief Frees internal resources used by a transport session + * + * @note + * - An endpoint must be bound to a valid protocomm instance, + * created using `protocomm_new()`. + * + * @param[in] pc Pointer to the protocomm instance + * @param[in] session_id Unique ID for a communication session + * + * @return + * - ESP_OK : Request handled successfully + * - ESP_ERR_INVALID_ARG : Null instance/name arguments + */ +esp_err_t protocomm_close_session(protocomm_t *pc, uint32_t session_id); + /** * @brief Calls the registered handler of an endpoint session * for processing incoming data and generating the response diff --git a/components/protocomm/src/common/protocomm.c b/components/protocomm/src/common/protocomm.c index 12b5b59ee3..e55ad7b890 100644 --- a/components/protocomm/src/common/protocomm.c +++ b/components/protocomm/src/common/protocomm.c @@ -149,6 +149,38 @@ esp_err_t protocomm_remove_endpoint(protocomm_t *pc, const char *ep_name) return ESP_ERR_NOT_FOUND; } +esp_err_t protocomm_open_session(protocomm_t *pc, uint32_t session_id) +{ + if (!pc) { + return ESP_ERR_INVALID_ARG; + } + + if (pc->sec && pc->sec->new_transport_session) { + esp_err_t ret = pc->sec->new_transport_session(pc->sec_inst, session_id); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to launch new session with ID: %d", session_id); + return ret; + } + } + return ESP_OK; +} + +esp_err_t protocomm_close_session(protocomm_t *pc, uint32_t session_id) +{ + if (!pc) { + return ESP_ERR_INVALID_ARG; + } + + if (pc->sec && pc->sec->close_transport_session) { + esp_err_t ret = pc->sec->close_transport_session(pc->sec_inst, session_id); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Error while closing session with ID: %d", session_id); + return ret; + } + } + return ESP_OK; +} + esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen) diff --git a/components/protocomm/test/test_protocomm.c b/components/protocomm/test/test_protocomm.c index d9a3a71a04..33d547b3d5 100644 --- a/components/protocomm/test/test_protocomm.c +++ b/components/protocomm/test/test_protocomm.c @@ -71,6 +71,7 @@ static const char *TAG = "protocomm_test"; static protocomm_t *test_pc = NULL; static const protocomm_security_t *test_sec = NULL; +protocomm_security_handle_t sec_inst = NULL; static uint32_t test_priv_data = 1234; static void flip_endian(uint8_t *data, size_t len) @@ -320,15 +321,37 @@ static esp_err_t test_new_session(session_t *session) return ESP_OK; } - if (!test_sec || !test_sec->new_transport_session) { + if (!test_sec) { return ESP_ERR_INVALID_STATE; } + if (test_sec->init && (test_sec->init(&sec_inst) != ESP_OK)) { + return ESP_ERR_NO_MEM; + } + uint32_t session_id = session->id; - if (test_sec->new_transport_session(session_id) != ESP_OK) { + if (test_sec->new_transport_session && + (test_sec->new_transport_session(sec_inst, session_id) != ESP_OK)) { ESP_LOGE(TAG, "Failed to launch new transport session"); return ESP_FAIL; } + + if (protocomm_open_session(test_pc, session_id) != ESP_OK) { + ESP_LOGE(TAG, "Failed to open new protocomm session"); + return ESP_FAIL; + } + return ESP_OK; +} + +static esp_err_t test_delete_session(session_t *session) +{ + if (!test_sec) { + return ESP_ERR_INVALID_STATE; + } + + if (test_sec->cleanup && (test_sec->cleanup(sec_inst) != ESP_OK)) { + return ESP_FAIL; + } return ESP_OK; } @@ -484,9 +507,11 @@ static esp_err_t test_sec_endpoint(session_t *session) mbedtls_ecdh_free(&session->ctx_client); mbedtls_ctr_drbg_free(&session->ctr_drbg); mbedtls_entropy_free(&session->entropy); + return ESP_OK; abort_test_sec_endpoint: + mbedtls_ecdh_free(&session->ctx_client); mbedtls_ctr_drbg_free(&session->ctr_drbg); mbedtls_entropy_free(&session->entropy); @@ -684,6 +709,7 @@ static esp_err_t test_security1_no_encryption (void) // Perform 25519 security handshake to set public keys if (test_sec_endpoint(session) != ESP_OK) { ESP_LOGE(TAG, "Error testing security endpoint"); + test_delete_session(session); stop_test_service(); free(session); return ESP_FAIL; @@ -697,11 +723,15 @@ static esp_err_t test_security1_no_encryption (void) // data to not match that which was sent, hence failing. if (test_req_endpoint(session) == ESP_OK) { ESP_LOGE(TAG, "Error testing request endpoint"); + session->sec_ver = 1; + test_delete_session(session); stop_test_service(); free(session); return ESP_FAIL; } + session->sec_ver = 1; + test_delete_session(session); stop_test_service(); free(session); ESP_LOGI(TAG, "Protocomm test successful"); @@ -759,6 +789,7 @@ static esp_err_t test_security1_session_overflow (void) // Perform 25519 security handshake to set public keys if (test_sec_endpoint(session1) != ESP_OK) { ESP_LOGE(TAG, "Error testing security endpoint"); + test_delete_session(session1); stop_test_service(); free(session1); free(session2); @@ -769,12 +800,14 @@ static esp_err_t test_security1_session_overflow (void) // session ID without registering new session, hence failing if (test_sec_endpoint(session2) == ESP_OK) { ESP_LOGE(TAG, "Error testing security endpoint"); + test_delete_session(session1); stop_test_service(); free(session1); free(session2); return ESP_FAIL; } + test_delete_session(session1); stop_test_service(); free(session1); free(session2); @@ -831,11 +864,13 @@ static esp_err_t test_security1_wrong_pop (void) // wrong pop, hence failing if (test_sec_endpoint(session) == ESP_OK) { ESP_LOGE(TAG, "Error testing security endpoint"); + test_delete_session(session); stop_test_service(); free(session); return ESP_FAIL; } + test_delete_session(session); stop_test_service(); free(session); @@ -935,6 +970,7 @@ static esp_err_t test_security1_weak_session (void) // client public key, hence failing if (test_sec_endpoint(session) == ESP_OK) { ESP_LOGE(TAG, "Error testing security endpoint"); + test_delete_session(session); stop_test_service(); free(session); return ESP_FAIL; @@ -944,11 +980,13 @@ static esp_err_t test_security1_weak_session (void) // public keys on both client and server side should fail if (test_req_endpoint(session) == ESP_OK) { ESP_LOGE(TAG, "Error testing request endpoint"); + test_delete_session(session); stop_test_service(); free(session); return ESP_FAIL; } + test_delete_session(session); stop_test_service(); free(session); @@ -983,6 +1021,7 @@ static esp_err_t test_protocomm (session_t *session) // Perform 25519 security handshake to set public keys if (test_sec_endpoint(session) != ESP_OK) { ESP_LOGE(TAG, "Error testing security endpoint"); + test_delete_session(session); stop_test_service(); return ESP_FAIL; } @@ -991,11 +1030,13 @@ static esp_err_t test_protocomm (session_t *session) // the set public keys on both client and server side if (test_req_endpoint(session) != ESP_OK) { ESP_LOGE(TAG, "Error testing request endpoint"); + test_delete_session(session); stop_test_service(); return ESP_FAIL; } // Stop protocomm service + test_delete_session(session); stop_test_service(); ESP_LOGI(TAG, "Protocomm test successful"); return ESP_OK;