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 | ||||
| ``` | ||||
| 
 | ||||
| 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 | ||||
| ``` | ||||
|  | ||||
| @ -16,7 +16,8 @@ function build_instance() { | ||||
|     mkdir occlum_$postfix | ||||
|     pushd occlum_$postfix | ||||
|     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 | ||||
| 
 | ||||
|     if [ "$postfix" == "server" ]; then | ||||
| @ -25,8 +26,10 @@ function build_instance() { | ||||
|              .verify_mr_signer = "on" | | ||||
|              .verify_isv_prod_id = "off" | | ||||
|              .verify_isv_svn = "off" | | ||||
|              .verify_enclave_debuggable = "on" | | ||||
| 	     .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 | ||||
|             cp /lib/x86_64-linux-gnu/libnss*.so.2 image/$occlum_glibc | ||||
| @ -35,11 +38,13 @@ function build_instance() { | ||||
| 
 | ||||
|         bomfile="../grpc_ratls_server.yaml" | ||||
|     else | ||||
|         # Client verify nothing from server | ||||
|         # Client verify only enclave non-debuggable from server | ||||
|         jq ' .verify_mr_enclave = "off" | | ||||
|              .verify_mr_signer = "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" | ||||
|     fi | ||||
| @ -52,9 +57,9 @@ function build_instance() { | ||||
| } | ||||
| 
 | ||||
| if [[ $1 == "musl" ]]; then | ||||
|     echo "*** Build and musl-libc Occlum instance ***" | ||||
|     echo "*** Build musl-libc Occlum instance ***" | ||||
| else | ||||
|     echo "*** Build and run glibc Occlum instance ***" | ||||
|     echo "*** Build glibc Occlum instance ***" | ||||
|     # glibc version requires libnss | ||||
|     libnss_require="y" | ||||
|     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_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_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 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")); | ||||
|         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; | ||||
| } | ||||
| @ -104,7 +111,8 @@ void ra_tls_verify_init() { | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
|     auto & sgx_cfg = _ctx_.sgx_cfg; | ||||
|     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; | ||||
|         } | ||||
| 
 | ||||
|         if (status && sgx_cfg.verify_enclave_debuggable && \ | ||||
|             (obj.debuggable != debuggable)) { | ||||
|             status = false; | ||||
|         } | ||||
| 
 | ||||
|         if (status) { | ||||
|             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, | ||||
|                        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); | ||||
|     bool status = false; | ||||
|     try { | ||||
|         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("  |- 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("  |- isv_prod_id    :  %hu\n", *((uint16_t*)isv_prod_id)); | ||||
|         grpc_printf("  |- isv_svn        :  %hu\n", *((uint16_t*)isv_svn)); | ||||
|         grpc_printf("  |- debuggable     :  %s", debuggable?"true":"false"); | ||||
|         if (status) { | ||||
|             grpc_printf("  |- verify result  :  success\n"); | ||||
|         } else { | ||||
|  | ||||
| @ -50,6 +50,7 @@ struct sgx_measurement { | ||||
|     char mr_signer[32]; | ||||
|     uint16_t isv_prod_id; | ||||
|     uint16_t isv_svn; | ||||
|     bool debuggable; | ||||
| }; | ||||
| 
 | ||||
| struct sgx_config { | ||||
| @ -57,6 +58,7 @@ struct sgx_config { | ||||
|     bool verify_mr_signer   = true; | ||||
|     bool verify_isv_prod_id = true; | ||||
|     bool verify_isv_svn     = true; | ||||
|     bool verify_enclave_debuggable = true; | ||||
|     std::vector<sgx_measurement> sgx_mrs; | ||||
| }; | ||||
| 
 | ||||
| @ -97,7 +99,8 @@ void ra_tls_parse_sgx_config(const char* file); | ||||
| void ra_tls_verify_init(); | ||||
| 
 | ||||
| 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); | ||||
| 
 | ||||
|  | ||||
| @ -299,10 +299,16 @@ int occlum_verify_cert(const unsigned char * der_crt, size_t len) { | ||||
|         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, | ||||
|                              (const char *)&p_rep_body->mr_signer, | ||||
|                              (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) { | ||||
|         grpc_printf("verify the measurement failed!\n"); | ||||
|         return -1; | ||||
|  | ||||
| @ -3,13 +3,14 @@ | ||||
|     "verify_mr_signer" : "on", | ||||
|     "verify_isv_prod_id" : "on", | ||||
|     "verify_isv_svn" : "on", | ||||
|     "verify_enclave_debuggable" : "on", | ||||
|     "sgx_mrs": [ | ||||
|         { | ||||
|             "mr_enclave" : "", | ||||
|             "mr_signer" : "", | ||||
|             "isv_prod_id" : "0", | ||||
|             "isv_svn" : "0" | ||||
|             "isv_svn" : "0", | ||||
|             "debuggable" : false | ||||
|         } | ||||
|     ], | ||||
|     "other" : [] | ||||
|     ] | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user