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