You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by ms...@apache.org on 2019/12/14 07:30:07 UTC

[incubator-teaclave] branch master updated: Use enclave_info.toml instead of txt (#155)

This is an automated email from the ASF dual-hosted git repository.

mssun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git


The following commit(s) were added to refs/heads/master by this push:
     new 8681ebd  Use enclave_info.toml instead of txt (#155)
8681ebd is described below

commit 8681ebd23c16e343462285fb07e64c9c99eb99e4
Author: Mingshen Sun <bo...@mssun.me>
AuthorDate: Fri Dec 13 23:30:00 2019 -0800

    Use enclave_info.toml instead of txt (#155)
    
    * Use enclave_info.toml instead of txt
    * Move sgx/utils in core to teaclave_utils
---
 cmake/MesaTEEUtils.cmake                      |   8 +-
 cmake/scripts/gen_enclave_info_toml.py        |  20 +++
 cmake/scripts/gen_enclave_sig.sh              |   8 +-
 cmake/scripts/sgx_link_sign.sh                |   2 +-
 docker/fns-rt.ubuntu-1604.Dockerfile          |   2 +-
 docker/fns-rt.ubuntu-1804.Dockerfile          |   2 +-
 docker/kms-rt.ubuntu-1604.Dockerfile          |   2 +-
 docker/kms-rt.ubuntu-1804.Dockerfile          |   2 +-
 docker/runtime.config.toml                    |   2 +-
 docker/tdfs-rt.ubuntu-1604.Dockerfile         |   2 +-
 docker/tdfs-rt.ubuntu-1804.Dockerfile         |   2 +-
 docker/tms-rt.ubuntu-1604.Dockerfile          |   2 +-
 docker/tms-rt.ubuntu-1804.Dockerfile          |   2 +-
 examples/dbscan/src/main.rs                   |   2 +-
 examples/gaussian_mixture_model/src/main.rs   |   2 +-
 examples/gaussian_processes/src/main.rs       |   2 +-
 examples/gbdt/src/main.rs                     |   2 +-
 examples/gen_linear_model/src/main.rs         |   2 +-
 examples/image_resizing/src/main.rs           |   2 +-
 examples/kmeans/src/main.rs                   |   2 +-
 examples/lin_reg/src/main.rs                  |   2 +-
 examples/logistic_reg/src/main.rs             |   2 +-
 examples/naive_bayes/src/main.rs              |   2 +-
 examples/neural_net/src/main.rs               |   2 +-
 examples/online_decrypt/src/main.rs           |   2 +-
 examples/private_join_and_compute/src/main.rs |   2 +-
 examples/py_file/src/main.rs                  |   2 +-
 examples/py_logistic_reg/src/main.rs          |   2 +-
 examples/py_matrix_multiply/src/main.rs       |   2 +-
 examples/quickstart/src/main.rs               |   2 +-
 examples/quickstart_c/main.c                  |   2 +-
 examples/rsa_sign/src/main.rs                 |   2 +-
 examples/svm/src/main.rs                      |   2 +-
 keys/auditors/README.md                       |   4 +-
 mesatee_cli/Cargo.toml                        |   1 +
 mesatee_cli/README.md                         |   2 +-
 mesatee_cli/src/main.rs                       |   7 +-
 mesatee_core/Cargo.toml                       |   4 +-
 mesatee_core/src/error.rs                     |  10 ++
 mesatee_core/src/lib.rs                       |   1 -
 mesatee_core/src/rpc/sgx/mod.rs               |   6 +-
 mesatee_core/src/rpc/sgx/ra.rs                |   6 +-
 mesatee_core/src/rpc/sgx/utils.rs             | 172 --------------------------
 mesatee_sdk/Cargo.toml                        |   3 +-
 mesatee_sdk/src/lib.rs                        |  16 +--
 mesatee_utils/teaclave_utils/Cargo.toml       |  20 +++
 mesatee_utils/teaclave_utils/src/lib.rs       | 146 ++++++++++++++++++++++
 teaclave_config/runtime.config.toml           |   2 +-
 48 files changed, 261 insertions(+), 235 deletions(-)

diff --git a/cmake/MesaTEEUtils.cmake b/cmake/MesaTEEUtils.cmake
index 2d412de..8c2f0cd 100644
--- a/cmake/MesaTEEUtils.cmake
+++ b/cmake/MesaTEEUtils.cmake
@@ -154,7 +154,7 @@ function(add_sgx_build_target sgx_lib_path pkg_name)
     if(_module_name STREQUAL "functional_test")
         set(_enclave_info "/dev/null")
     else()
-        set(_enclave_info "${MESATEE_OUT_DIR}/${_module_name}_enclave_info.txt")
+        set(_enclave_info "${MESATEE_OUT_DIR}/${_module_name}_enclave_info.toml")
     endif()
 
     add_custom_target(${_target_name} ALL
@@ -164,10 +164,8 @@ function(add_sgx_build_target sgx_lib_path pkg_name)
         COMMAND ${CMAKE_COMMAND} -E env ${TARGET_SGXLIB_ENVS} SGX_COMMON_CFLAGS=${STR_SGX_COMMON_CFLAGS}
             CUR_MODULE_NAME=${_module_name} CUR_MODULE_PATH=${sgx_lib_path} CUR_INSTALL_DIR=${_copy_dir} ${MT_SCRIPT_DIR}/sgx_link_sign.sh
         ${_depends}
-        COMMAND echo ${_module_name} > ${_enclave_info}
-        COMMAND grep -m1 -A2 "mrsigner->value" ${MESATEE_OUT_DIR}/${_module_name}.enclave.meta.txt >> ${_enclave_info}
-        COMMAND grep -m1 -A2 "body.enclave_hash" ${MESATEE_OUT_DIR}/${_module_name}.enclave.meta.txt >> ${_enclave_info}
-        COMMENT "Building ${_target_name}, enclave info to ${ENCLAVE_INFO}"
+        COMMAND cat ${MESATEE_OUT_DIR}/${_module_name}.enclave.meta.txt | python ${MT_SCRIPT_DIR}/gen_enclave_info_toml.py ${_module_name} > ${_enclave_info}
+        COMMENT "Building ${_target_name}, enclave info to ${_enclave_info}"
         WORKING_DIRECTORY ${MT_SGXLIB_TOML_DIR}
     )
 endfunction()
diff --git a/cmake/scripts/gen_enclave_info_toml.py b/cmake/scripts/gen_enclave_info_toml.py
new file mode 100644
index 0000000..f6a4ecf
--- /dev/null
+++ b/cmake/scripts/gen_enclave_info_toml.py
@@ -0,0 +1,20 @@
+import sys
+
+def find_hex_value(content, section):
+    index = content.index(section)
+    # assume each element in content is ending with '\n'
+    hex_bytes = ''.join(content[index+1:index+3]).split()
+    return ''.join(['%02x' % int(x, 16) for x in hex_bytes])
+
+mrsigner = "mrsigner->value:\n"
+enclave_hash = "metadata->enclave_css.body.enclave_hash.m:\n"
+
+content = sys.stdin.readlines()
+
+mrsigner_hex = find_hex_value(content, mrsigner)
+enclave_hash_hex = find_hex_value(content, enclave_hash)
+
+sys.stdout.write("""[{}]
+mrsigner     = "{}"
+enclave_hash = "{}"
+""".format(sys.argv[1], mrsigner_hex, enclave_hash_hex))
diff --git a/cmake/scripts/gen_enclave_sig.sh b/cmake/scripts/gen_enclave_sig.sh
index a8bd181..3b9105e 100755
--- a/cmake/scripts/gen_enclave_sig.sh
+++ b/cmake/scripts/gen_enclave_sig.sh
@@ -5,7 +5,7 @@ for var in "${REQUIRED_ENVS[@]}"; do
     [ -z "${!var}" ] && echo "Please set ${var}" && exit -1
 done
 
-cd ${MESATEE_OUT_DIR} && cat *_enclave_info.txt > ${MESATEE_SERVICE_INSTALL_DIR}/enclave_info.txt
+cd ${MESATEE_OUT_DIR} && cat *_enclave_info.toml > ${MESATEE_SERVICE_INSTALL_DIR}/enclave_info.toml
 
 AUDITOR_PATHS=$(find ${MESATEE_AUDITORS_DIR} -mindepth 1 -maxdepth 1 -type d)
 for auditor_path in ${AUDITOR_PATHS}; do
@@ -13,10 +13,10 @@ auditor=$(basename ${auditor_path})
 openssl dgst -sha256 \
         -sign ${MESATEE_AUDITORS_DIR}/${auditor}/${auditor}.private.pem \
         -out ${MESATEE_AUDITORS_DIR}/${auditor}/${auditor}.sign.sha256 \
-        ${MESATEE_SERVICE_INSTALL_DIR}/enclave_info.txt;
+        ${MESATEE_SERVICE_INSTALL_DIR}/enclave_info.toml;
 done
 
 cp -RT ${MESATEE_AUDITORS_DIR}/ ${MESATEE_EXAMPLE_AUDITORS_DIR}/
 cp -r ${MESATEE_AUDITORS_DIR} ${MESATEE_TEST_INSTALL_DIR}/
-cp ${MESATEE_SERVICE_INSTALL_DIR}/enclave_info.txt ${MESATEE_EXAMPLE_INSTALL_DIR}/
-cp ${MESATEE_SERVICE_INSTALL_DIR}/enclave_info.txt ${MESATEE_TEST_INSTALL_DIR}/
+cp ${MESATEE_SERVICE_INSTALL_DIR}/enclave_info.toml ${MESATEE_EXAMPLE_INSTALL_DIR}/
+cp ${MESATEE_SERVICE_INSTALL_DIR}/enclave_info.toml ${MESATEE_TEST_INSTALL_DIR}/
diff --git a/cmake/scripts/sgx_link_sign.sh b/cmake/scripts/sgx_link_sign.sh
index a594930..fac6e34 100755
--- a/cmake/scripts/sgx_link_sign.sh
+++ b/cmake/scripts/sgx_link_sign.sh
@@ -11,7 +11,7 @@ done
 LIBENCLAVE_PATH="${TRUSTED_TARGET_DIR}/${TARGET}/lib${CUR_MODULE_NAME}_enclave.a"
 CONFIG_PATH="${MESATEE_PROJECT_ROOT}/${CUR_MODULE_PATH}/Enclave.config.xml"
 SIGNED_PATH="${CUR_INSTALL_DIR}/${CUR_MODULE_NAME}.enclave.signed.so"
-CUR_ENCLAVE_INFO_PATH="${MESATEE_OUT_DIR}/${CUR_MODULE_NAME}_enclave_info.txt"
+CUR_ENCLAVE_INFO_PATH="${MESATEE_OUT_DIR}/${CUR_MODULE_NAME}_enclave_info.toml"
 if [ ! "$LIBENCLAVE_PATH" -nt "$SIGNED_PATH" ] \
     && [ ! "$CONFIG_PATH" -nt "$SIGNED_PATH" ] \
     && [  ! "$SIGNED_PATH" -nt "$CUR_ENCLAVE_INFO_PATH" ]; then
diff --git a/docker/fns-rt.ubuntu-1604.Dockerfile b/docker/fns-rt.ubuntu-1604.Dockerfile
index ea1ffcc..91c0f4a 100644
--- a/docker/fns-rt.ubuntu-1604.Dockerfile
+++ b/docker/fns-rt.ubuntu-1604.Dockerfile
@@ -16,7 +16,7 @@ RUN wget -O $LIBSGX_ENCLAVE_COMMON "$LIBSGX_ENCLAVE_COMMON_URL" && \
 
 ADD release/services/fns /mesatee/
 ADD release/services/fns.enclave.signed.so /mesatee/
-ADD release/services/enclave_info.txt /mesatee/
+ADD release/services/enclave_info.toml /mesatee/
 ADD release/services/auditors /mesatee/auditors
 
 ENTRYPOINT ["/mesatee/fns"]
diff --git a/docker/fns-rt.ubuntu-1804.Dockerfile b/docker/fns-rt.ubuntu-1804.Dockerfile
index 0ff9043..fab54dc 100644
--- a/docker/fns-rt.ubuntu-1804.Dockerfile
+++ b/docker/fns-rt.ubuntu-1804.Dockerfile
@@ -16,7 +16,7 @@ RUN wget -O $LIBSGX_ENCLAVE_COMMON "$LIBSGX_ENCLAVE_COMMON_URL" && \
 
 ADD release/services/fns /mesatee/
 ADD release/services/fns.enclave.signed.so /mesatee/
-ADD release/services/enclave_info.txt /mesatee/
+ADD release/services/enclave_info.toml /mesatee/
 ADD release/services/auditors /mesatee/auditors
 
 ENTRYPOINT ["/mesatee/fns"]
diff --git a/docker/kms-rt.ubuntu-1604.Dockerfile b/docker/kms-rt.ubuntu-1604.Dockerfile
index e04971d..5296bf0 100644
--- a/docker/kms-rt.ubuntu-1604.Dockerfile
+++ b/docker/kms-rt.ubuntu-1604.Dockerfile
@@ -16,7 +16,7 @@ RUN wget -O $LIBSGX_ENCLAVE_COMMON "$LIBSGX_ENCLAVE_COMMON_URL" && \
 
 ADD release/services/kms /mesatee/
 ADD release/services/kms.enclave.signed.so /mesatee/
-ADD release/services/enclave_info.txt /mesatee/
+ADD release/services/enclave_info.toml /mesatee/
 ADD release/services/auditors /mesatee/auditors
 
 ENTRYPOINT ["/mesatee/kms"]
diff --git a/docker/kms-rt.ubuntu-1804.Dockerfile b/docker/kms-rt.ubuntu-1804.Dockerfile
index 0ff79e8..d5b1488 100644
--- a/docker/kms-rt.ubuntu-1804.Dockerfile
+++ b/docker/kms-rt.ubuntu-1804.Dockerfile
@@ -16,7 +16,7 @@ RUN wget -O $LIBSGX_ENCLAVE_COMMON "$LIBSGX_ENCLAVE_COMMON_URL" && \
 
 ADD release/services/kms /mesatee/
 ADD release/services/kms.enclave.signed.so /mesatee/
-ADD release/services/enclave_info.txt /mesatee/
+ADD release/services/enclave_info.toml /mesatee/
 ADD release/services/auditors /mesatee/auditors
 
 ENTRYPOINT ["/mesatee/kms"]
diff --git a/docker/runtime.config.toml b/docker/runtime.config.toml
index fde9c79..8f66596 100644
--- a/docker/runtime.config.toml
+++ b/docker/runtime.config.toml
@@ -39,7 +39,7 @@ kms  = { listen_address = "0.0.0.0:6016", advertised_address = "172.18.18.102:60
 acs  = { listen_address = "0.0.0.0:5077", advertised_address = "172.18.18.103:5077" }
 
 [audit]
-enclave_info = { path = "enclave_info.txt" }
+enclave_info = { path = "enclave_info.toml" }
 auditor_signatures = [
     { path = "auditors/godzilla/godzilla.sign.sha256" },
     { path = "auditors/optimus_prime/optimus_prime.sign.sha256" },
diff --git a/docker/tdfs-rt.ubuntu-1604.Dockerfile b/docker/tdfs-rt.ubuntu-1604.Dockerfile
index 4d64d1a..e56a894 100644
--- a/docker/tdfs-rt.ubuntu-1604.Dockerfile
+++ b/docker/tdfs-rt.ubuntu-1604.Dockerfile
@@ -16,7 +16,7 @@ RUN wget -O $LIBSGX_ENCLAVE_COMMON "$LIBSGX_ENCLAVE_COMMON_URL" && \
 
 ADD release/services/tdfs /mesatee/
 ADD release/services/tdfs.enclave.signed.so /mesatee/
-ADD release/services/enclave_info.txt /mesatee/
+ADD release/services/enclave_info.toml /mesatee/
 ADD release/services/auditors /mesatee/auditors
 
 ENTRYPOINT ["/mesatee/tdfs"]
diff --git a/docker/tdfs-rt.ubuntu-1804.Dockerfile b/docker/tdfs-rt.ubuntu-1804.Dockerfile
index 46cd2ba..8a31e35 100644
--- a/docker/tdfs-rt.ubuntu-1804.Dockerfile
+++ b/docker/tdfs-rt.ubuntu-1804.Dockerfile
@@ -16,7 +16,7 @@ RUN wget -O $LIBSGX_ENCLAVE_COMMON "$LIBSGX_ENCLAVE_COMMON_URL" && \
 
 ADD release/services/tdfs /mesatee/
 ADD release/services/tdfs.enclave.signed.so /mesatee/
-ADD release/services/enclave_info.txt /mesatee/
+ADD release/services/enclave_info.toml /mesatee/
 ADD release/services/auditors /mesatee/auditors
 
 ENTRYPOINT ["/mesatee/tdfs"]
diff --git a/docker/tms-rt.ubuntu-1604.Dockerfile b/docker/tms-rt.ubuntu-1604.Dockerfile
index b58a9a8..bc07761 100644
--- a/docker/tms-rt.ubuntu-1604.Dockerfile
+++ b/docker/tms-rt.ubuntu-1604.Dockerfile
@@ -16,7 +16,7 @@ RUN wget -O $LIBSGX_ENCLAVE_COMMON "$LIBSGX_ENCLAVE_COMMON_URL" && \
 
 ADD release/services/tms /mesatee/
 ADD release/services/tms.enclave.signed.so /mesatee/
-ADD release/services/enclave_info.txt /mesatee/
+ADD release/services/enclave_info.toml /mesatee/
 ADD release/services/auditors /mesatee/auditors
 
 ENTRYPOINT ["/mesatee/tms"]
diff --git a/docker/tms-rt.ubuntu-1804.Dockerfile b/docker/tms-rt.ubuntu-1804.Dockerfile
index 4880e1f..4e8e3be 100644
--- a/docker/tms-rt.ubuntu-1804.Dockerfile
+++ b/docker/tms-rt.ubuntu-1804.Dockerfile
@@ -16,7 +16,7 @@ RUN wget -O $LIBSGX_ENCLAVE_COMMON "$LIBSGX_ENCLAVE_COMMON_URL" && \
 
 ADD release/services/tms /mesatee/
 ADD release/services/tms.enclave.signed.so /mesatee/
-ADD release/services/enclave_info.txt /mesatee/
+ADD release/services/enclave_info.toml /mesatee/
 ADD release/services/auditors /mesatee/auditors
 
 ENTRYPOINT ["/mesatee/tms"]
diff --git a/examples/dbscan/src/main.rs b/examples/dbscan/src/main.rs
index 7fff58b..b16c149 100644
--- a/examples/dbscan/src/main.rs
+++ b/examples/dbscan/src/main.rs
@@ -84,7 +84,7 @@ fn main() {
     };
 
     let input_string = serde_json::to_string(&input_payload).unwrap();
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let mesatee = Mesatee::new(
         &mesatee_enclave_info,
diff --git a/examples/gaussian_mixture_model/src/main.rs b/examples/gaussian_mixture_model/src/main.rs
index f3d3258..d93b60d 100644
--- a/examples/gaussian_mixture_model/src/main.rs
+++ b/examples/gaussian_mixture_model/src/main.rs
@@ -93,7 +93,7 @@ fn main() {
     };
 
     let input_string = serde_json::to_string(&input_payload).unwrap();
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let mesatee = Mesatee::new(
         &mesatee_enclave_info,
diff --git a/examples/gaussian_processes/src/main.rs b/examples/gaussian_processes/src/main.rs
index ffc8f3d..857bfdb 100644
--- a/examples/gaussian_processes/src/main.rs
+++ b/examples/gaussian_processes/src/main.rs
@@ -100,7 +100,7 @@ fn main() {
     };
 
     let input_string = serde_json::to_string(&input_payload).unwrap();
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let mesatee = Mesatee::new(
         &mesatee_enclave_info,
diff --git a/examples/gbdt/src/main.rs b/examples/gbdt/src/main.rs
index e8485d0..0d1a45a 100644
--- a/examples/gbdt/src/main.rs
+++ b/examples/gbdt/src/main.rs
@@ -113,7 +113,7 @@ fn main() {
         ),
     ];
 
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
 
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let args: Vec<String> = env::args().collect();
diff --git a/examples/gen_linear_model/src/main.rs b/examples/gen_linear_model/src/main.rs
index ada224d..8ef65d8 100644
--- a/examples/gen_linear_model/src/main.rs
+++ b/examples/gen_linear_model/src/main.rs
@@ -100,7 +100,7 @@ fn main() {
     };
 
     let input_string = serde_json::to_string(&input_payload).unwrap();
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let mesatee = Mesatee::new(
         &mesatee_enclave_info,
diff --git a/examples/image_resizing/src/main.rs b/examples/image_resizing/src/main.rs
index 933505c..4330798 100644
--- a/examples/image_resizing/src/main.rs
+++ b/examples/image_resizing/src/main.rs
@@ -64,7 +64,7 @@ fn main() {
             "../services/auditors/albus_dumbledore/albus_dumbledore.sign.sha256",
         ),
     ];
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
 
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
 
diff --git a/examples/kmeans/src/main.rs b/examples/kmeans/src/main.rs
index 6d16b87..9a1a94e 100644
--- a/examples/kmeans/src/main.rs
+++ b/examples/kmeans/src/main.rs
@@ -85,7 +85,7 @@ fn main() {
     };
     let input_string = serde_json::to_string(&input_payload).unwrap();
 
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
 
     let mesatee = Mesatee::new(
diff --git a/examples/lin_reg/src/main.rs b/examples/lin_reg/src/main.rs
index efd0423..a280aa0 100644
--- a/examples/lin_reg/src/main.rs
+++ b/examples/lin_reg/src/main.rs
@@ -100,7 +100,7 @@ fn main() {
     };
 
     let input_string = serde_json::to_string(&input_payload).unwrap();
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let mesatee = Mesatee::new(
         &mesatee_enclave_info,
diff --git a/examples/logistic_reg/src/main.rs b/examples/logistic_reg/src/main.rs
index 7bb4d8b..67b7521 100644
--- a/examples/logistic_reg/src/main.rs
+++ b/examples/logistic_reg/src/main.rs
@@ -94,7 +94,7 @@ fn main() {
         ),
     ];
 
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
 
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let args_string: Vec<String> = env::args().collect();
diff --git a/examples/naive_bayes/src/main.rs b/examples/naive_bayes/src/main.rs
index 8a2aa08..43c9b57 100644
--- a/examples/naive_bayes/src/main.rs
+++ b/examples/naive_bayes/src/main.rs
@@ -92,7 +92,7 @@ fn main() {
     };
 
     let input_string = serde_json::to_string(&input_payload).unwrap();
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let mesatee = Mesatee::new(
         &mesatee_enclave_info,
diff --git a/examples/neural_net/src/main.rs b/examples/neural_net/src/main.rs
index 20e684b..cce6ab0 100644
--- a/examples/neural_net/src/main.rs
+++ b/examples/neural_net/src/main.rs
@@ -99,7 +99,7 @@ fn main() {
     };
 
     let input_string = serde_json::to_string(&input_payload).unwrap();
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let mesatee = Mesatee::new(
         &mesatee_enclave_info,
diff --git a/examples/online_decrypt/src/main.rs b/examples/online_decrypt/src/main.rs
index f581a60..4fe7631 100644
--- a/examples/online_decrypt/src/main.rs
+++ b/examples/online_decrypt/src/main.rs
@@ -157,7 +157,7 @@ fn main() {
             "../services/auditors/albus_dumbledore/albus_dumbledore.sign.sha256",
         ),
     ];
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
 
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
 
diff --git a/examples/private_join_and_compute/src/main.rs b/examples/private_join_and_compute/src/main.rs
index 7826b3d..6ed34f3 100644
--- a/examples/private_join_and_compute/src/main.rs
+++ b/examples/private_join_and_compute/src/main.rs
@@ -139,7 +139,7 @@ fn main() {
             "../services/auditors/albus_dumbledore/albus_dumbledore.sign.sha256",
         ),
     ];
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
 
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
 
diff --git a/examples/py_file/src/main.rs b/examples/py_file/src/main.rs
index a588bc7..a00d7f4 100644
--- a/examples/py_file/src/main.rs
+++ b/examples/py_file/src/main.rs
@@ -44,7 +44,7 @@ fn main() {
             "../services/auditors/albus_dumbledore/albus_dumbledore.sign.sha256",
         ),
     ];
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
 
     let args_string: Vec<String> = env::args().collect();
diff --git a/examples/py_logistic_reg/src/main.rs b/examples/py_logistic_reg/src/main.rs
index 05eeb08..997bc34 100644
--- a/examples/py_logistic_reg/src/main.rs
+++ b/examples/py_logistic_reg/src/main.rs
@@ -44,7 +44,7 @@ fn main() {
             "../services/auditors/albus_dumbledore/albus_dumbledore.sign.sha256",
         ),
     ];
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
 
     let args_string: Vec<String> = env::args().collect();
diff --git a/examples/py_matrix_multiply/src/main.rs b/examples/py_matrix_multiply/src/main.rs
index 57e5c19..8245d47 100644
--- a/examples/py_matrix_multiply/src/main.rs
+++ b/examples/py_matrix_multiply/src/main.rs
@@ -44,7 +44,7 @@ fn main() {
             "../services/auditors/albus_dumbledore/albus_dumbledore.sign.sha256",
         ),
     ];
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
 
     let args_string: Vec<String> = env::args().collect();
diff --git a/examples/quickstart/src/main.rs b/examples/quickstart/src/main.rs
index 02656de..8606cba 100644
--- a/examples/quickstart/src/main.rs
+++ b/examples/quickstart/src/main.rs
@@ -92,7 +92,7 @@ fn main() {
             "../services/auditors/albus_dumbledore/albus_dumbledore.sign.sha256",
         ),
     ];
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
 
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
 
diff --git a/examples/quickstart_c/main.c b/examples/quickstart_c/main.c
index 25e28c9..e56cf90 100644
--- a/examples/quickstart_c/main.c
+++ b/examples/quickstart_c/main.c
@@ -71,7 +71,7 @@ int main() {
   assert(auditors != NULL);
 
   mesatee_enclave_info_t *enclave_info =
-      mesatee_enclave_info_load(auditors, "../services/enclave_info.txt");
+      mesatee_enclave_info_load(auditors, "../services/enclave_info.toml");
 
   assert(enclave_info != NULL);
 
diff --git a/examples/rsa_sign/src/main.rs b/examples/rsa_sign/src/main.rs
index 0e33892..1ebeb34 100644
--- a/examples/rsa_sign/src/main.rs
+++ b/examples/rsa_sign/src/main.rs
@@ -75,7 +75,7 @@ fn main() {
             "../services/auditors/albus_dumbledore/albus_dumbledore.sign.sha256",
         ),
     ];
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
 
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
 
diff --git a/examples/svm/src/main.rs b/examples/svm/src/main.rs
index 635d070..cf2b527 100644
--- a/examples/svm/src/main.rs
+++ b/examples/svm/src/main.rs
@@ -100,7 +100,7 @@ fn main() {
     };
 
     let input_string = serde_json::to_string(&input_payload).unwrap();
-    let enclave_info_file_path = "../services/enclave_info.txt";
+    let enclave_info_file_path = "../services/enclave_info.toml";
     let mesatee_enclave_info = MesateeEnclaveInfo::load(auditors, enclave_info_file_path).unwrap();
     let mesatee = Mesatee::new(
         &mesatee_enclave_info,
diff --git a/keys/auditors/README.md b/keys/auditors/README.md
index e455cc7..377041b 100644
--- a/keys/auditors/README.md
+++ b/keys/auditors/README.md
@@ -6,10 +6,10 @@ Each auditor has his/her own asymmetric key pair and will sign MesaTEE enclaves
 only if the enclaves can pass the audting process:
 
 ```
-openssl dgst -sha256 -sign private.pem -out sign.sha256 enclave_info.txt
+openssl dgst -sha256 -sign private.pem -out sign.sha256 enclave_info.toml
 ```
 
-The enclave_info.txt above contains the MRSIGNER (enclave signer's identity)
+The enclave_info.toml above contains the MRSIGNER (enclave signer's identity)
 and MRENCLAVE (enclave's measurement) value pairs of all MesaTEE enclaves. A
 sample entry looks like:
 
diff --git a/mesatee_cli/Cargo.toml b/mesatee_cli/Cargo.toml
index 3f93725..59aa21b 100644
--- a/mesatee_cli/Cargo.toml
+++ b/mesatee_cli/Cargo.toml
@@ -21,3 +21,4 @@ clap_flags = "0.2.0"
 tms_external_proto = { path = "../mesatee_services/tms/external/proto" }
 tdfs_external_proto = { path = "../mesatee_services/tdfs/external/proto" }
 fns_proto = { path = "../mesatee_services/fns/proto" }
+teaclave_utils = { path = "../mesatee_utils/teaclave_utils" }
diff --git a/mesatee_cli/README.md b/mesatee_cli/README.md
index 403d087..a051965 100644
--- a/mesatee_cli/README.md
+++ b/mesatee_cli/README.md
@@ -66,7 +66,7 @@ Here we give an example of using `mesatee_cli`:
 ```shell
 $ cd mesatee
 $ ./service.sh start
-$ ./bin/mesatee_cli 127.0.0.1:5554 -k auditors/albus_dumbledore/albus_dumbledore.public.der -k auditors/godzilla/godzilla.public.der -k auditors/optimus_prime/optimus_prime.public.der -s auditors/albus_dumbledore/albus_dumbledore.sign.sha256 -s auditors/godzilla/godzilla.sign.sha256 -s auditors/optimus_prime/optimus_prime.sign.sha256 -c out/enclave_info.txt --endpoint tms -i ~/tms_payload
+$ ./bin/mesatee_cli 127.0.0.1:5554 -k auditors/albus_dumbledore/albus_dumbledore.public.der -k auditors/godzilla/godzilla.public.der -k auditors/optimus_prime/optimus_prime.public.der -s auditors/albus_dumbledore/albus_dumbledore.sign.sha256 -s auditors/godzilla/godzilla.sign.sha256 -s auditors/optimus_prime/optimus_prime.sign.sha256 -c out/enclave_info.toml --endpoint tms -i ~/tms_payload
 
 {"type":"Create","task_id":"7216dd3e-ab3a-4974-b03e-3833891bbb26","task_token":"08e0d4c807700ff24d31ca01d8695b61","ip":"127.0.0.1","port":3444}
 ```
diff --git a/mesatee_cli/src/main.rs b/mesatee_cli/src/main.rs
index 01a5ee3..155e125 100644
--- a/mesatee_cli/src/main.rs
+++ b/mesatee_cli/src/main.rs
@@ -27,6 +27,7 @@ use fns_proto::{InvokeTaskRequest, InvokeTaskResponse};
 use mesatee_core::config::{OutboundDesc, TargetDesc};
 use mesatee_core::rpc::{channel, sgx};
 use tdfs_external_proto::{DFSRequest, DFSResponse};
+use teaclave_utils;
 use tms_external_proto::{TaskRequest, TaskResponse};
 
 type EnclaveInfo = std::collections::HashMap<String, (sgx::SgxMeasure, sgx::SgxMeasure)>;
@@ -141,8 +142,10 @@ fn main() -> CliResult {
         let (key, sig_path) = auditor;
         enclave_signers.push((key.as_slice(), sig_path.as_path()));
     }
-    let enclave_info =
-        sgx::load_and_verify_enclave_info(&args.enclave_info, enclave_signers.as_slice());
+    let enclave_info = teaclave_utils::load_and_verify_enclave_info(
+        &args.enclave_info,
+        enclave_signers.as_slice(),
+    );
 
     let reader: Box<dyn Read> = match args.input {
         Some(i) => Box::new(io::BufReader::new(fs::File::open(i)?)),
diff --git a/mesatee_core/Cargo.toml b/mesatee_core/Cargo.toml
index 3a06674..16562bb 100644
--- a/mesatee_core/Cargo.toml
+++ b/mesatee_core/Cargo.toml
@@ -12,7 +12,7 @@ path = "src/lib.rs"
 
 [features]
 default = []
-mesalock_sgx = ["sgx_tstd", "sgx_tcrypto", "sgx_rand", "sgx_tse", "ipc", "teaclave_config/mesalock_sgx"]
+mesalock_sgx = ["sgx_tstd", "sgx_tcrypto", "sgx_rand", "sgx_tse", "ipc", "teaclave_config/mesalock_sgx", "teaclave_utils/mesalock_sgx"]
 ipc = []
 
 [dependencies]
@@ -34,6 +34,7 @@ bit-vec      = { version = "0.6.1", default-features = false }
 httparse     = { version = "1.3.2", default-features = false }
 uuid         = { version = "0.7.4", features = ["v4"] }
 net2         = { version = "0.2.33" }
+toml         = { version = "0.5.3" }
 
 sgx_tstd  = { version = "1.0.9", features = ["net"], optional = true }
 sgx_types = { version = "1.0.9" }
@@ -43,4 +44,5 @@ sgx_rand  = { version = "1.0.9", optional = true }
 sgx_tse   = { version = "1.0.9", optional = true }
 
 teaclave_config = { path = "../teaclave_config" }
+teaclave_utils = { path = "../mesatee_utils/teaclave_utils" }
 ipc_attribute = { path = "./ipc_attribute" }
diff --git a/mesatee_core/src/error.rs b/mesatee_core/src/error.rs
index 1ed297c..7946801 100644
--- a/mesatee_core/src/error.rs
+++ b/mesatee_core/src/error.rs
@@ -21,6 +21,7 @@ use std::prelude::v1::*;
 
 use std::fmt;
 use std::{io, net};
+use teaclave_utils;
 
 pub type Result<T> = std::result::Result<T, Error>;
 
@@ -436,6 +437,15 @@ impl From<sgx_types::sgx_status_t> for Error {
     }
 }
 
+impl From<teaclave_utils::UtilsError> for Error {
+    #[inline]
+    fn from(err: teaclave_utils::UtilsError) -> Error {
+        match err {
+            teaclave_utils::UtilsError::ParseError => Error::from(ErrorKind::ParseError),
+        }
+    }
+}
+
 #[repr(u32)]
 #[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Debug)]
 pub enum SgxStatus {
diff --git a/mesatee_core/src/lib.rs b/mesatee_core/src/lib.rs
index e9f61b6..b7af8a1 100644
--- a/mesatee_core/src/lib.rs
+++ b/mesatee_core/src/lib.rs
@@ -31,7 +31,6 @@ extern crate ring;
 
 pub mod db;
 pub mod rpc; // Syntax sugar for monadic error handling, defined in mayfail.rs
-#[cfg(not(feature = "mesalock_sgx"))]
 pub mod utils;
 
 // MesaTEE Error is defined in error.rs
diff --git a/mesatee_core/src/rpc/sgx/mod.rs b/mesatee_core/src/rpc/sgx/mod.rs
index 68fbacc..8aeb327 100644
--- a/mesatee_core/src/rpc/sgx/mod.rs
+++ b/mesatee_core/src/rpc/sgx/mod.rs
@@ -38,13 +38,11 @@ use crate::Result;
 
 use teaclave_config::build_config::BUILD_CONFIG;
 use teaclave_config::runtime_config::RUNTIME_CONFIG;
+use teaclave_utils;
 
 #[macro_use]
 mod fail;
 
-mod utils;
-pub use utils::load_and_verify_enclave_info;
-
 pub mod client;
 #[cfg(feature = "mesalock_sgx")]
 pub mod server;
@@ -90,7 +88,7 @@ pub(crate) fn load_presigned_enclave_info() -> HashMap<String, (SgxMeasure, SgxM
         ),
     ];
 
-    utils::load_and_verify_enclave_info(&enclave_info_path, enclave_signers.as_slice())
+    teaclave_utils::load_and_verify_enclave_info(&enclave_info_path, enclave_signers.as_slice())
 }
 
 #[derive(Clone)]
diff --git a/mesatee_core/src/rpc/sgx/ra.rs b/mesatee_core/src/rpc/sgx/ra.rs
index c9ac7bd..2169070 100644
--- a/mesatee_core/src/rpc/sgx/ra.rs
+++ b/mesatee_core/src/rpc/sgx/ra.rs
@@ -45,12 +45,12 @@ use std::untrusted::time::SystemTimeEx;
 use lazy_static::lazy_static;
 
 use super::fail::MayfailTrace;
-use super::utils::*;
 use crate::Error;
 use crate::ErrorKind;
 use crate::Result;
 
 use teaclave_config::runtime_config::RUNTIME_CONFIG;
+use teaclave_utils;
 
 pub const CERT_VALID_DAYS: i64 = 90i64;
 
@@ -197,7 +197,7 @@ fn parse_response_attn_report(resp: &[u8]) -> Result<AttnReport> {
                     // Remove %0A from cert, and only obtain the signing cert
                     let cert = cert_str.to_string().replace("%0A", "");
                     // We should get two concatenated PEM files at this step
-                    decoded_cert =<< percent_decode(cert);
+                    decoded_cert =<< teaclave_utils::percent_decode(cert);
                     let cert_content: Vec<&str> = decoded_cert.split("-----").collect();
                     _ =<< if cert_content.len() != 9 { None } else { Some(()) };
                     ret cert_content[2].to_string()
@@ -412,7 +412,7 @@ fn create_attestation_report(pub_k: &sgx_ec256_public_t) -> Result<AttnReport> {
     let spid_vec = load_spid(&RUNTIME_CONFIG.env.ias_spid)?;
 
     let spid_str = std::str::from_utf8(&spid_vec)?;
-    let spid: sgx_spid_t = decode_spid(spid_str)?;
+    let spid: sgx_spid_t = teaclave_utils::decode_spid(spid_str)?;
 
     let p_spid = &spid as *const sgx_spid_t;
     let p_nonce = &quote_nonce as *const sgx_quote_nonce_t;
diff --git a/mesatee_core/src/rpc/sgx/utils.rs b/mesatee_core/src/rpc/sgx/utils.rs
deleted file mode 100644
index 32f519a..0000000
--- a/mesatee_core/src/rpc/sgx/utils.rs
+++ /dev/null
@@ -1,172 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-#[cfg(feature = "mesalock_sgx")]
-use std::prelude::v1::*;
-
-use crate::Error;
-use crate::ErrorKind;
-use crate::Result;
-
-fn decode_hex_digit(digit: char) -> Result<u8> {
-    match digit {
-        '0'..='9' => Ok(digit as u8 - b'0'),
-        'a'..='f' => Ok(digit as u8 - b'a' + 10),
-        'A'..='F' => Ok(digit as u8 - b'A' + 10),
-        _ => Err(Error::from(ErrorKind::ParseError)),
-    }
-}
-
-#[cfg(feature = "mesalock_sgx")]
-pub(crate) fn decode_hex(hex: &str) -> Result<Vec<u8>> {
-    let mut r: Vec<u8> = Vec::new();
-    let mut chars = hex.chars().enumerate();
-    loop {
-        let (_, first) = match chars.next() {
-            None => break,
-            Some(elt) => elt,
-        };
-        if first == ' ' {
-            continue;
-        }
-        let (_, second) = chars
-            .next()
-            .ok_or_else(|| Error::from(ErrorKind::ParseError))?;
-        r.push((decode_hex_digit(first)? << 4) | decode_hex_digit(second)?);
-    }
-    Ok(r)
-}
-
-#[cfg(feature = "mesalock_sgx")]
-pub(crate) fn decode_spid(hex: &str) -> Result<sgx_types::sgx_spid_t> {
-    let mut spid = sgx_types::sgx_spid_t::default();
-    let hex = hex.trim();
-
-    if hex.len() < 16 * 2 {
-        debug!("Input spid file len ({}) is incorrect!", hex.len());
-        return Ok(spid);
-    }
-
-    let decoded_vec = decode_hex(hex)?;
-
-    spid.id.copy_from_slice(&decoded_vec[..16]);
-
-    Ok(spid)
-}
-
-#[cfg(feature = "mesalock_sgx")]
-pub(crate) fn percent_decode(orig: String) -> Result<String> {
-    let v: Vec<&str> = orig.split('%').collect();
-    let mut ret = String::new();
-    ret.push_str(v[0]);
-    if v.len() > 1 {
-        for s in v[1..].iter() {
-            let digit =
-                u8::from_str_radix(&s[0..2], 16).map_err(|_| Error::from(ErrorKind::ParseError))?;
-            ret.push(digit as char);
-            ret.push_str(&s[2..]);
-        }
-    }
-    Ok(ret)
-}
-
-use super::SgxMeasure;
-
-fn decode_sgx_measure(lines: [&str; 2]) -> Result<SgxMeasure> {
-    let decoded_hash: Vec<u8> = lines
-        .iter()
-        .map(|line| line.trim().split(' '))
-        .flatten()
-        .try_fold(Vec::<u8>::new(), |mut r, hex| -> Result<Vec<u8>> {
-            // skip "0x"
-            let mut hex = hex.chars().skip(2);
-
-            use super::fail::MayfailNop;
-            let byte = mayfail! {
-                first =<< hex.next();
-                second =<< hex.next();
-                first_digit =<< decode_hex_digit(first);
-                second_digit =<< decode_hex_digit(second);
-                ret first_digit * 16 + second_digit
-            }?;
-            r.push(byte);
-            Ok(r)
-        })?;
-    let mut sgx_measure = [0u8; 32];
-    sgx_measure[..].copy_from_slice(decoded_hash.as_slice());
-
-    Ok(sgx_measure)
-}
-
-// This function fails when enclave info signatures mismatch hard-coded
-// auditor keys. We expect the program to crash in those cases
-pub fn load_and_verify_enclave_info(
-    enclave_info_file_path: &std::path::Path,
-    // A vector of signer meta info, each tuple is
-    // (harded-coded public key, file path to signature of enclave_info.txt)
-    enclave_signers: &[(&[u8], &std::path::Path)],
-) -> std::collections::HashMap<String, (SgxMeasure, SgxMeasure)> {
-    #[cfg(not(feature = "mesalock_sgx"))]
-    use std::fs::File;
-    #[cfg(feature = "mesalock_sgx")]
-    use std::untrusted::fs::File;
-
-    use std::io::Read;
-
-    let mut content = String::new();
-    let mut f_enclave_info = File::open(enclave_info_file_path)
-        .unwrap_or_else(|_| panic!("cannot find enclave info at {:?}", enclave_info_file_path));
-    f_enclave_info
-        .read_to_string(&mut content)
-        .expect("cannot read from enclave info file");
-
-    // verify autenticity of enclave identity info
-    for signer in enclave_signers {
-        let mut sig_file = File::open(signer.1)
-            .unwrap_or_else(|_| panic!("cannot find signature file at {:?}", signer.1));
-        let mut sig = Vec::<u8>::new();
-        sig_file
-            .read_to_end(&mut sig)
-            .unwrap_or_else(|_| panic!("cannot read signature from {:?}", signer.1));
-
-        use ring::signature;
-        let public_key =
-            signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256, signer.0);
-        public_key
-            .verify(content.as_bytes(), sig.as_slice())
-            .expect("invalid signature for enclave info file");
-    }
-
-    let lines: Vec<&str> = content.split('\n').collect();
-    let mut info_map = std::collections::HashMap::new();
-    lines
-        .as_slice()
-        .chunks_exact(7)
-        .try_for_each(|group| -> Result<()> {
-            let name = String::from(group[0]);
-
-            let mr_signer = decode_sgx_measure([group[2], group[3]])?;
-            let mr_enclave = decode_sgx_measure([group[5], group[6]])?;
-
-            info_map.insert(name, (mr_signer, mr_enclave));
-
-            Ok(())
-        })
-        .expect("malformed enclave info file");
-
-    info_map
-}
diff --git a/mesatee_sdk/Cargo.toml b/mesatee_sdk/Cargo.toml
index 58a23dc..ecc200b 100644
--- a/mesatee_sdk/Cargo.toml
+++ b/mesatee_sdk/Cargo.toml
@@ -11,4 +11,5 @@ tdfs_external_client = { path = "../mesatee_services/tdfs/external/client" }
 tms_external_client  = { path = "../mesatee_services/tms/external/client" }
 tms_external_proto   = { path = "../mesatee_services/tms/external/proto" }
 fns_client           = { path = "../mesatee_services/fns/client" }
-mesatee_core = { version = "0.1.0" }
\ No newline at end of file
+mesatee_core = { version = "0.1.0" }
+teaclave_utils = { path = "../mesatee_utils/teaclave_utils" }
\ No newline at end of file
diff --git a/mesatee_sdk/src/lib.rs b/mesatee_sdk/src/lib.rs
index f9d1478..d0ad1f4 100644
--- a/mesatee_sdk/src/lib.rs
+++ b/mesatee_sdk/src/lib.rs
@@ -105,7 +105,7 @@
 //! generated by a tool from Intel called `sgx_sign` during compilation.
 //!
 //! The current MesaTEE project generate a file containing all of the included
-//! Intel SGX enclaves, and saved it at `{PROJECT_ROOT}/release/services/enclave_info.txt`.
+//! Intel SGX enclaves, and saved it at `{PROJECT_ROOT}/release/services/enclave_info.toml`.
 //!
 //! In a classic multi-party computation scenario, every participant **must**
 //! agree with these measurements before any collaboration. In MesaTEE, this
@@ -115,8 +115,8 @@
 //!
 //! The auditors hold their own private keys and publish their public keys.
 //! Once the auditors agree with the measurements, he/she needs to sign the
-//! `enclave_info.txt` with his/her private key, and saves the SHA256 digest
-//! of `enclave_info.txt`.
+//! `enclave_info.toml` with his/her private key, and saves the SHA256 digest
+//! of `enclave_info.toml`.
 //!
 //! To launch a MesaTEE task for multi-party computation, the one who invokes
 //! the `Mesatee::new` API needs to collect each participant's public key
@@ -200,13 +200,13 @@
 
 use fns_client::FNSClient;
 use mesatee_core::config::{OutboundDesc, TargetDesc};
-use mesatee_core::rpc::sgx;
 pub use mesatee_core::{Error, ErrorKind, Result};
 use std::fs;
 use std::net::SocketAddr;
 use std::path::{Path, PathBuf};
 use std::str::FromStr;
 use tdfs_external_client::TDFSClient;
+use teaclave_utils;
 use tms_external_client::TMSClient;
 pub use tms_external_proto::TaskStatus;
 
@@ -295,9 +295,9 @@ pub struct TaskInfo {
 /// at
 pub struct MesateeEnclaveInfo {
     /// `enclave_signers` holds a list of "auditor's public key", and
-    /// "auditor's copy of sha256 digest of enclave_info.txt".
+    /// "auditor's copy of sha256 digest of enclave_info.toml".
     enclave_signers: Vec<(Vec<u8>, PathBuf)>,
-    /// holds the path of `enclave_info.txt`.
+    /// holds the path of `enclave_info.toml`.
     enclave_info_file_path: PathBuf,
 }
 
@@ -311,7 +311,7 @@ impl MesateeEnclaveInfo {
     /// "Auditors" participated in the consensus of MRENCLAVEs and MRSIGNERs.
     /// The tuple `(&str, &str)` means "auditor's public key in DER format",
     ///
-    /// * `enclave_info_file_path` - holds the file path of `enclave_info.txt`.
+    /// * `enclave_info_file_path` - holds the file path of `enclave_info.toml`.
     ///
     /// # Return Value
     ///
@@ -380,7 +380,7 @@ impl Mesatee {
         for (der, hash) in enclave_info.enclave_signers.iter() {
             enclave_signers.push((&der, hash.as_path()));
         }
-        let enclave_identities = sgx::load_and_verify_enclave_info(
+        let enclave_identities = teaclave_utils::load_and_verify_enclave_info(
             &enclave_info.enclave_info_file_path,
             &enclave_signers,
         );
diff --git a/mesatee_utils/teaclave_utils/Cargo.toml b/mesatee_utils/teaclave_utils/Cargo.toml
new file mode 100644
index 0000000..2138b00
--- /dev/null
+++ b/mesatee_utils/teaclave_utils/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "teaclave_utils"
+version = "0.1.0"
+authors = ["MesaTEE Authors <de...@mesatee.org>"]
+description = "MesaTEE utilities."
+license = "Apache-2.0"
+edition = "2018"
+
+[features]
+default = []
+mesalock_sgx = ["sgx_tstd"]
+
+[dependencies]
+log          = { version = "0.4.6" }
+ring         = { version = "0.16.5" }
+serde        = { version = "1.0.92" }
+serde_derive = { version = "1.0.92" }
+sgx_tstd     = { version = "1.0.9", optional = true }
+sgx_types    = { version = "1.0.9" }
+toml         = { version = "0.5.3" }
diff --git a/mesatee_utils/teaclave_utils/src/lib.rs b/mesatee_utils/teaclave_utils/src/lib.rs
new file mode 100644
index 0000000..bfcec33
--- /dev/null
+++ b/mesatee_utils/teaclave_utils/src/lib.rs
@@ -0,0 +1,146 @@
+#![cfg_attr(feature = "mesalock_sgx", no_std)]
+#[cfg(feature = "mesalock_sgx")]
+extern crate sgx_tstd as std;
+#[cfg(feature = "mesalock_sgx")]
+use std::prelude::v1::*;
+
+#[macro_use]
+extern crate log;
+use serde::Deserializer;
+use serde_derive::Deserialize;
+use std::collections::HashMap;
+
+type Result<T> = std::result::Result<T, UtilsError>;
+type SgxMeasure = [u8; 32];
+
+pub enum UtilsError {
+    ParseError,
+}
+
+fn decode_hex_digit(digit: char) -> Result<u8> {
+    match digit {
+        '0'..='9' => Ok(digit as u8 - b'0'),
+        'a'..='f' => Ok(digit as u8 - b'a' + 10),
+        'A'..='F' => Ok(digit as u8 - b'A' + 10),
+        _ => Err(UtilsError::ParseError),
+    }
+}
+
+pub fn decode_hex(hex: &str) -> Result<Vec<u8>> {
+    let mut r: Vec<u8> = Vec::new();
+    let mut chars = hex.chars().enumerate();
+    loop {
+        let (_, first) = match chars.next() {
+            None => break,
+            Some(elt) => elt,
+        };
+        if first == ' ' {
+            continue;
+        }
+        let (_, second) = chars.next().ok_or_else(|| UtilsError::ParseError)?;
+        r.push((decode_hex_digit(first)? << 4) | decode_hex_digit(second)?);
+    }
+    Ok(r)
+}
+
+pub fn decode_spid(hex: &str) -> Result<sgx_types::sgx_spid_t> {
+    let mut spid = sgx_types::sgx_spid_t::default();
+    let hex = hex.trim();
+
+    if hex.len() < 16 * 2 {
+        debug!("Input spid file len ({}) is incorrect!", hex.len());
+        return Ok(spid);
+    }
+
+    let decoded_vec = decode_hex(hex)?;
+
+    spid.id.copy_from_slice(&decoded_vec[..16]);
+
+    Ok(spid)
+}
+
+pub fn percent_decode(orig: String) -> Result<String> {
+    let v: Vec<&str> = orig.split('%').collect();
+    let mut ret = String::new();
+    ret.push_str(v[0]);
+    if v.len() > 1 {
+        for s in v[1..].iter() {
+            let digit = u8::from_str_radix(&s[0..2], 16).map_err(|_| UtilsError::ParseError)?;
+            ret.push(digit as char);
+            ret.push_str(&s[2..]);
+        }
+    }
+    Ok(ret)
+}
+
+/// Deserializes a hex string to a `SgxMeasure` (i.e., [0; 32]).
+pub fn from_hex<'de, D>(deserializer: D) -> std::result::Result<SgxMeasure, D::Error>
+where
+    D: Deserializer<'de>,
+{
+    use serde::de::Error;
+    use serde::Deserialize;
+    String::deserialize(deserializer).and_then(|string| {
+        let v = decode_hex(&string).map_err(|_| Error::custom("ParseError"))?;
+        let mut array: SgxMeasure = [0; 32];
+        let bytes = &v[..array.len()]; // panics if not enough data
+        array.copy_from_slice(bytes);
+        Ok(array)
+    })
+}
+
+#[derive(Debug, Deserialize)]
+#[serde(transparent)]
+struct EnclaveInfoToml(HashMap<String, EnclaveInfo>);
+
+#[derive(Debug, Deserialize)]
+struct EnclaveInfo {
+    #[serde(deserialize_with = "from_hex")]
+    mrsigner: SgxMeasure,
+    #[serde(deserialize_with = "from_hex")]
+    enclave_hash: SgxMeasure,
+}
+
+// This function fails when enclave info signatures mismatch hard-coded
+// auditor keys. We expect the program to crash in those cases
+pub fn load_and_verify_enclave_info(
+    enclave_info_file_path: &std::path::Path,
+    // A vector of signer meta info, each tuple is
+    // (harded-coded public key, file path to signature of enclave_info.toml)
+    enclave_signers: &[(&[u8], &std::path::Path)],
+) -> std::collections::HashMap<String, (SgxMeasure, SgxMeasure)> {
+    #[cfg(not(feature = "mesalock_sgx"))]
+    use std::fs::{self, File};
+    #[cfg(feature = "mesalock_sgx")]
+    use std::untrusted::fs::{self, File};
+
+    use std::io::Read;
+
+    let content = fs::read_to_string(enclave_info_file_path)
+        .unwrap_or_else(|_| panic!("cannot find enclave info at {:?}", enclave_info_file_path));
+
+    // verify autenticity of enclave identity info
+    for signer in enclave_signers {
+        let mut sig_file = File::open(signer.1)
+            .unwrap_or_else(|_| panic!("cannot find signature file at {:?}", signer.1));
+        let mut sig = Vec::<u8>::new();
+        sig_file
+            .read_to_end(&mut sig)
+            .unwrap_or_else(|_| panic!("cannot read signature from {:?}", signer.1));
+
+        use ring::signature;
+        let public_key =
+            signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256, signer.0);
+        public_key
+            .verify(content.as_bytes(), sig.as_slice())
+            .expect("invalid signature for enclave info file");
+    }
+    let config: EnclaveInfoToml =
+        toml::from_str(&content).expect("Content not correct, unable to load enclave info.");
+    let mut info_map = std::collections::HashMap::new();
+    for (k, v) in config.0 {
+        info_map.insert(k, (v.mrsigner, v.enclave_hash));
+    }
+
+    info_map
+}
diff --git a/teaclave_config/runtime.config.toml b/teaclave_config/runtime.config.toml
index a321f66..37afab3 100644
--- a/teaclave_config/runtime.config.toml
+++ b/teaclave_config/runtime.config.toml
@@ -39,7 +39,7 @@ kms  = { listen_address = "0.0.0.0:6016", advertised_address = "127.0.0.1:6016"
 acs  = { listen_address = "0.0.0.0:5077", advertised_address = "127.0.0.1:5077" }
 
 [audit]
-enclave_info = { path = "enclave_info.txt" }
+enclave_info = { path = "enclave_info.toml" }
 auditor_signatures = [
     { path = "auditors/godzilla/godzilla.sign.sha256" },
     { path = "auditors/optimus_prime/optimus_prime.sign.sha256" },


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org