Add enclave debuggable verification for ra_tls
This commit is contained in:
		
							parent
							
								
									2d7fbefcc2
								
							
						
					
					
						commit
						f4665dac11
					
				| @ -55,7 +55,7 @@ If musl-libc version is expected. | |||||||
| ./build_and_install.sh musl | ./build_and_install.sh musl | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| The following command will generate the client and server occlum images. It automatically parses the mr_enclave and mr_signer of the client, and write the value into dynamic_config.json. If you want to verify the other measurements of client, please modify the dynamic_config.json before run the script. | The following command will generate the client and server occlum images. It automatically parses the mr_enclave and mr_signer of the client, and write the value into dynamic_config.json. If you want to verify the other measurements of client, please modify the `ra_config_template.json` before run the script. | ||||||
| ``` | ``` | ||||||
| ./build_occlum_instance.sh | ./build_occlum_instance.sh | ||||||
| ``` | ``` | ||||||
|  | |||||||
| @ -16,7 +16,8 @@ function build_instance() { | |||||||
|     mkdir occlum_$postfix |     mkdir occlum_$postfix | ||||||
|     pushd occlum_$postfix |     pushd occlum_$postfix | ||||||
|     occlum init |     occlum init | ||||||
|     new_json="$(jq '.resource_limits.user_space_size = "500MB"' Occlum.json)" && \ |     new_json="$(jq '.resource_limits.user_space_size = "500MB" | | ||||||
|  |                     .metadata.debuggable = false' Occlum.json)" && \ | ||||||
|     echo "${new_json}" > Occlum.json |     echo "${new_json}" > Occlum.json | ||||||
| 
 | 
 | ||||||
|     if [ "$postfix" == "server" ]; then |     if [ "$postfix" == "server" ]; then | ||||||
| @ -25,8 +26,10 @@ function build_instance() { | |||||||
|              .verify_mr_signer = "on" | |              .verify_mr_signer = "on" | | ||||||
|              .verify_isv_prod_id = "off" | |              .verify_isv_prod_id = "off" | | ||||||
|              .verify_isv_svn = "off" | |              .verify_isv_svn = "off" | | ||||||
|  |              .verify_enclave_debuggable = "on" | | ||||||
| 	     .sgx_mrs[0].mr_enclave = ''"'`get_mr client mr_enclave`'" | | 	     .sgx_mrs[0].mr_enclave = ''"'`get_mr client mr_enclave`'" | | ||||||
| 	     .sgx_mrs[0].mr_signer = ''"'`get_mr client mr_signer`'" ' ../ra_config_template.json > dynamic_config.json | 	     .sgx_mrs[0].mr_signer = ''"'`get_mr client mr_signer`'" | | ||||||
|  |          .sgx_mrs[0].debuggable = false ' ../ra_config_template.json > dynamic_config.json | ||||||
|      |      | ||||||
|         if [ "$libnss_require" == "y" ]; then |         if [ "$libnss_require" == "y" ]; then | ||||||
|             cp /lib/x86_64-linux-gnu/libnss*.so.2 image/$occlum_glibc |             cp /lib/x86_64-linux-gnu/libnss*.so.2 image/$occlum_glibc | ||||||
| @ -35,11 +38,13 @@ function build_instance() { | |||||||
| 
 | 
 | ||||||
|         bomfile="../grpc_ratls_server.yaml" |         bomfile="../grpc_ratls_server.yaml" | ||||||
|     else |     else | ||||||
|         # Client verify nothing from server |         # Client verify only enclave non-debuggable from server | ||||||
|         jq ' .verify_mr_enclave = "off" | |         jq ' .verify_mr_enclave = "off" | | ||||||
|              .verify_mr_signer = "off" | |              .verify_mr_signer = "off" | | ||||||
|              .verify_isv_prod_id = "off" | |              .verify_isv_prod_id = "off" | | ||||||
|              .verify_isv_svn = "off" ' ../ra_config_template.json > dynamic_config.json |              .verify_isv_svn = "off" | | ||||||
|  |              .verify_enclave_debuggable = "on" | | ||||||
|  |              .sgx_mrs[0].debuggable = false ' ../ra_config_template.json > dynamic_config.json | ||||||
| 
 | 
 | ||||||
|         bomfile="../grpc_ratls_client.yaml" |         bomfile="../grpc_ratls_client.yaml" | ||||||
|     fi |     fi | ||||||
| @ -52,9 +57,9 @@ function build_instance() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| if [[ $1 == "musl" ]]; then | if [[ $1 == "musl" ]]; then | ||||||
|     echo "*** Build and musl-libc Occlum instance ***" |     echo "*** Build musl-libc Occlum instance ***" | ||||||
| else | else | ||||||
|     echo "*** Build and run glibc Occlum instance ***" |     echo "*** Build glibc Occlum instance ***" | ||||||
|     # glibc version requires libnss |     # glibc version requires libnss | ||||||
|     libnss_require="y" |     libnss_require="y" | ||||||
|     occlum_glibc=/opt/occlum/glibc/lib/ |     occlum_glibc=/opt/occlum/glibc/lib/ | ||||||
|  | |||||||
| @ -1,68 +0,0 @@ | |||||||
| #include "sgx_ra_tls_utils.h" |  | ||||||
| #include "sgx_ra_tls_backend.h" |  | ||||||
| #include "sgx_quote_3.h" |  | ||||||
| #include "occlum_dcap.h" |  | ||||||
| 
 |  | ||||||
| namespace grpc { |  | ||||||
| namespace sgx { |  | ||||||
| int verify_quote (uint8_t * quote_buffer, size_t quote_size) { |  | ||||||
|     void *handle; |  | ||||||
|     handle = dcap_quote_open(); |  | ||||||
|     uint32_t supplemental_size, ret; |  | ||||||
|     uint8_t *p_supplemental_buffer; |  | ||||||
|     sgx_ql_qv_result_t quote_verification_result = SGX_QL_QV_RESULT_UNSPECIFIED; |  | ||||||
|     uint32_t collateral_expiration_status = 1; |  | ||||||
|     supplemental_size = dcap_get_supplemental_data_size(handle); |  | ||||||
|     p_supplemental_buffer = (uint8_t *)malloc(supplemental_size); |  | ||||||
|     if (NULL == p_supplemental_buffer) { |  | ||||||
|         printf("Couldn't allocate supplemental buffer\n"); |  | ||||||
|     } |  | ||||||
|     memset(p_supplemental_buffer, 0, supplemental_size); |  | ||||||
|     ret = dcap_verify_quote( |  | ||||||
|         handle, |  | ||||||
|         quote_buffer, |  | ||||||
|         quote_size, |  | ||||||
|         &collateral_expiration_status, |  | ||||||
|         "e_verification_result, |  | ||||||
|         supplemental_size, |  | ||||||
|         p_supplemental_buffer |  | ||||||
|         ); |  | ||||||
|      |  | ||||||
|     if (0 != ret) { |  | ||||||
|         printf( "Error in dcap_verify_quote.\n"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (collateral_expiration_status != 0) { |  | ||||||
|         printf("the verification collateral has expired\n"); |  | ||||||
|     } |  | ||||||
|     dcap_quote_close(handle); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int generate_quote(uint8_t *quote_buffer, unsigned char *hash, size_t hash_len) { |  | ||||||
|   void *handle; |  | ||||||
| 
 |  | ||||||
|   handle = dcap_quote_open(); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   sgx_report_data_t report_data = { 0 }; |  | ||||||
|   memcpy(report_data.d, hash, hash_len); |  | ||||||
| 
 |  | ||||||
|   // Get the Quote
 |  | ||||||
|   int ret = dcap_generate_quote(handle, quote_buffer, &report_data); |  | ||||||
|   if (0 != ret) { |  | ||||||
|     printf( "Error in dcap_generate_quote.\n"); |  | ||||||
|   } |  | ||||||
|   |  | ||||||
|   dcap_quote_close(handle); |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint32_t get_quote_size() { |  | ||||||
|   void *handle = dcap_quote_open(); |  | ||||||
|   uint32_t quote_size = dcap_get_quote_size(handle); |  | ||||||
|   dcap_quote_close(handle); |  | ||||||
|   return quote_size; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| }//namespace grpc
 |  | ||||||
| }//namesapce sgx
 |  | ||||||
| @ -1,41 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * |  | ||||||
|  * Copyright 2019 gRPC authors. |  | ||||||
|  * |  | ||||||
|  * Licensed 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. |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef SGX_RA_TLS_BACKEND_H |  | ||||||
| #define SGX_RA_TLS_BACKEND_H |  | ||||||
| 
 |  | ||||||
| #include <string> |  | ||||||
| #include <memory> |  | ||||||
| #include <sstream> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| namespace grpc { |  | ||||||
| namespace sgx { |  | ||||||
| 
 |  | ||||||
| int verify_quote (uint8_t * quote_buffer, size_t quote_size); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| int generate_quote(uint8_t *quote_buffer, unsigned char *hash, size_t hash_len); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| uint32_t get_quote_size(); |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| } |  | ||||||
| #endif  // SGX_RA_TLS_BACKEND_H
 |  | ||||||
| @ -65,6 +65,8 @@ static sgx_config parse_sgx_config_json(const char* file) { | |||||||
|     sgx_cfg.verify_mr_signer = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_mr_signer"), "on"); |     sgx_cfg.verify_mr_signer = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_mr_signer"), "on"); | ||||||
|     sgx_cfg.verify_isv_prod_id = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_prod_id"), "on"); |     sgx_cfg.verify_isv_prod_id = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_prod_id"), "on"); | ||||||
|     sgx_cfg.verify_isv_svn = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_svn"), "on"); |     sgx_cfg.verify_isv_svn = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_svn"), "on"); | ||||||
|  |     sgx_cfg.verify_enclave_debuggable = | ||||||
|  |         sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_enclave_debuggable"), "on"); | ||||||
| 
 | 
 | ||||||
|     auto objs = sgx_json.get_item(sgx_json.get_handle(), "sgx_mrs"); |     auto objs = sgx_json.get_item(sgx_json.get_handle(), "sgx_mrs"); | ||||||
|     auto obj_num = std::min(cJSON_GetArraySize(objs), SGX_MESUREMENTS_MAX_SIZE); |     auto obj_num = std::min(cJSON_GetArraySize(objs), SGX_MESUREMENTS_MAX_SIZE); | ||||||
| @ -86,6 +88,11 @@ static sgx_config parse_sgx_config_json(const char* file) { | |||||||
| 
 | 
 | ||||||
|         auto isv_svn = sgx_json.print_item(sgx_json.get_item(obj, "isv_svn")); |         auto isv_svn = sgx_json.print_item(sgx_json.get_item(obj, "isv_svn")); | ||||||
|         sgx_cfg.sgx_mrs[i].isv_svn = strtoul(isv_svn, nullptr, 10); |         sgx_cfg.sgx_mrs[i].isv_svn = strtoul(isv_svn, nullptr, 10); | ||||||
|  | 
 | ||||||
|  |         if (cJSON_IsTrue(sgx_json.get_item(obj, "debuggable")) == 0) | ||||||
|  |             sgx_cfg.sgx_mrs[i].debuggable = false; | ||||||
|  |         else | ||||||
|  |             sgx_cfg.sgx_mrs[i].debuggable = true; | ||||||
|     }; |     }; | ||||||
|     return sgx_cfg; |     return sgx_cfg; | ||||||
| } | } | ||||||
| @ -104,7 +111,8 @@ void ra_tls_verify_init() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool verify_measurement_internal(const char* mr_enclave, const char* mr_signer, | static bool verify_measurement_internal(const char* mr_enclave, const char* mr_signer, | ||||||
|                                         const char* isv_prod_id, const char* isv_svn) { |                                         const char* isv_prod_id, const char* isv_svn, | ||||||
|  |                                         bool debuggable) { | ||||||
|     bool status = false; |     bool status = false; | ||||||
|     auto & sgx_cfg = _ctx_.sgx_cfg; |     auto & sgx_cfg = _ctx_.sgx_cfg; | ||||||
|     for (auto & obj : sgx_cfg.sgx_mrs) { |     for (auto & obj : sgx_cfg.sgx_mrs) { | ||||||
| @ -130,6 +138,11 @@ static bool verify_measurement_internal(const char* mr_enclave, const char* mr_s | |||||||
|             status = false; |             status = false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (status && sgx_cfg.verify_enclave_debuggable && \ | ||||||
|  |             (obj.debuggable != debuggable)) { | ||||||
|  |             status = false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (status) { |         if (status) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| @ -138,17 +151,19 @@ static bool verify_measurement_internal(const char* mr_enclave, const char* mr_s | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int verify_measurement(const char* mr_enclave, const char* mr_signer, | int verify_measurement(const char* mr_enclave, const char* mr_signer, | ||||||
|                        const char* isv_prod_id, const char* isv_svn) { |                        const char* isv_prod_id, const char* isv_svn, | ||||||
|  |                        bool debuggable) { | ||||||
|     std::lock_guard<std::mutex> lock(_ctx_.mtx); |     std::lock_guard<std::mutex> lock(_ctx_.mtx); | ||||||
|     bool status = false; |     bool status = false; | ||||||
|     try { |     try { | ||||||
|         assert(mr_enclave && mr_signer && isv_prod_id && isv_svn); |         assert(mr_enclave && mr_signer && isv_prod_id && isv_svn); | ||||||
|         status = verify_measurement_internal(mr_enclave, mr_signer, isv_prod_id, isv_svn); |         status = verify_measurement_internal(mr_enclave, mr_signer, isv_prod_id, isv_svn, debuggable); | ||||||
|         grpc_printf("remote sgx measurements\n");  |         grpc_printf("remote sgx measurements\n");  | ||||||
|         grpc_printf("  |- mr_enclave     :  %s\n", byte_to_hex(mr_enclave, 32).c_str()); |         grpc_printf("  |- mr_enclave     :  %s\n", byte_to_hex(mr_enclave, 32).c_str()); | ||||||
|         grpc_printf("  |- mr_signer      :  %s\n", byte_to_hex(mr_signer, 32).c_str()); |         grpc_printf("  |- mr_signer      :  %s\n", byte_to_hex(mr_signer, 32).c_str()); | ||||||
|         grpc_printf("  |- isv_prod_id    :  %hu\n", *((uint16_t*)isv_prod_id)); |         grpc_printf("  |- isv_prod_id    :  %hu\n", *((uint16_t*)isv_prod_id)); | ||||||
|         grpc_printf("  |- isv_svn        :  %hu\n", *((uint16_t*)isv_svn)); |         grpc_printf("  |- isv_svn        :  %hu\n", *((uint16_t*)isv_svn)); | ||||||
|  |         grpc_printf("  |- debuggable     :  %s", debuggable?"true":"false"); | ||||||
|         if (status) { |         if (status) { | ||||||
|             grpc_printf("  |- verify result  :  success\n"); |             grpc_printf("  |- verify result  :  success\n"); | ||||||
|         } else { |         } else { | ||||||
|  | |||||||
| @ -50,6 +50,7 @@ struct sgx_measurement { | |||||||
|     char mr_signer[32]; |     char mr_signer[32]; | ||||||
|     uint16_t isv_prod_id; |     uint16_t isv_prod_id; | ||||||
|     uint16_t isv_svn; |     uint16_t isv_svn; | ||||||
|  |     bool debuggable; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct sgx_config { | struct sgx_config { | ||||||
| @ -57,6 +58,7 @@ struct sgx_config { | |||||||
|     bool verify_mr_signer   = true; |     bool verify_mr_signer   = true; | ||||||
|     bool verify_isv_prod_id = true; |     bool verify_isv_prod_id = true; | ||||||
|     bool verify_isv_svn     = true; |     bool verify_isv_svn     = true; | ||||||
|  |     bool verify_enclave_debuggable = true; | ||||||
|     std::vector<sgx_measurement> sgx_mrs; |     std::vector<sgx_measurement> sgx_mrs; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -97,7 +99,8 @@ void ra_tls_parse_sgx_config(const char* file); | |||||||
| void ra_tls_verify_init(); | void ra_tls_verify_init(); | ||||||
| 
 | 
 | ||||||
| int verify_measurement(const char* mr_enclave, const char* mr_signer, | int verify_measurement(const char* mr_enclave, const char* mr_signer, | ||||||
|                        const char* isv_prod_id, const char* isv_svn); |                        const char* isv_prod_id, const char* isv_svn, | ||||||
|  |                        bool debuggable); | ||||||
| 
 | 
 | ||||||
| void credential_option_set_certificate_provider(grpc::sgx::CredentialsOptions& options); | void credential_option_set_certificate_provider(grpc::sgx::CredentialsOptions& options); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -299,10 +299,16 @@ int occlum_verify_cert(const unsigned char * der_crt, size_t len) { | |||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Check if enclave is debuggable
 | ||||||
|  |     bool debuggable = false; | ||||||
|  |     if (p_rep_body->attributes.flags & SGX_FLAGS_DEBUG) | ||||||
|  |         debuggable = true; | ||||||
|  | 
 | ||||||
|     ret = verify_measurement((const char *)&p_rep_body->mr_enclave, |     ret = verify_measurement((const char *)&p_rep_body->mr_enclave, | ||||||
|                              (const char *)&p_rep_body->mr_signer, |                              (const char *)&p_rep_body->mr_signer, | ||||||
|                              (const char *)&p_rep_body->isv_prod_id, |                              (const char *)&p_rep_body->isv_prod_id, | ||||||
|                              (const char *)&p_rep_body->isv_svn);  |                              (const char *)&p_rep_body->isv_svn, | ||||||
|  |                              debuggable); | ||||||
|     if (ret != 0) { |     if (ret != 0) { | ||||||
|         grpc_printf("verify the measurement failed!\n"); |         grpc_printf("verify the measurement failed!\n"); | ||||||
|         return -1; |         return -1; | ||||||
|  | |||||||
| @ -3,13 +3,14 @@ | |||||||
|     "verify_mr_signer" : "on", |     "verify_mr_signer" : "on", | ||||||
|     "verify_isv_prod_id" : "on", |     "verify_isv_prod_id" : "on", | ||||||
|     "verify_isv_svn" : "on", |     "verify_isv_svn" : "on", | ||||||
|  |     "verify_enclave_debuggable" : "on", | ||||||
|     "sgx_mrs": [ |     "sgx_mrs": [ | ||||||
|         { |         { | ||||||
|             "mr_enclave" : "", |             "mr_enclave" : "", | ||||||
|             "mr_signer" : "", |             "mr_signer" : "", | ||||||
|             "isv_prod_id" : "0", |             "isv_prod_id" : "0", | ||||||
|             "isv_svn" : "0" |             "isv_svn" : "0", | ||||||
|  |             "debuggable" : false | ||||||
|         } |         } | ||||||
|     ], |     ] | ||||||
|     "other" : [] |  | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user