]> granicus.if.org Git - esp-idf/commitdiff
Protocomm : Added new APIs for opening and closing secure sessions
authorAnurag Kar <anurag.kar@espressif.com>
Mon, 15 Apr 2019 13:06:09 +0000 (18:36 +0530)
committerAnurag Kar <anurag.kar@espressif.com>
Tue, 16 Apr 2019 08:20:01 +0000 (13:50 +0530)
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

components/protocomm/include/common/protocomm.h
components/protocomm/src/common/protocomm.c
components/protocomm/test/test_protocomm.c

index 239d71390b293ad3094454024bed5d1847d5675f..cb11a0b132f30b3c61fd9aa957b181d6245e02f0 100644 (file)
@@ -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
index 12b5b59ee3bc7fe4f36e961230a000b3c19f6fdd..e55ad7b8901305edff362da92c7b2586193ae30a 100644 (file)
@@ -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)
index d9a3a71a0407814905e08b3b7d2c025fcedf7ba4..33d547b3d58ba458c3cbefb8369694d8c46d0129 100644 (file)
@@ -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;