Skip to content
This repository was archived by the owner on Jan 27, 2022. It is now read-only.

Commit 2f9f763

Browse files
committed
Changes to verify MR enclave value in client side
1. verify IAS report utility which verifies MR enclave 2. generic client shows the usage. Signed-off-by: Ramakrishna Srinivasamurthy <[email protected]>
1 parent 41b49c5 commit 2f9f763

File tree

7 files changed

+107
-13
lines changed

7 files changed

+107
-13
lines changed

common/cpp/verify_ias_report/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,22 @@ add_custom_command(OUTPUT ${PROJECT_GENERATED_IAS_SOURCES}
4242
# Untrusted Verify-Ias-Report Library
4343
################################################################################
4444

45+
SET(SGX_SDK "$ENV{SGX_SDK}")
46+
SET(SGX_SDK_INCLUDE ${SGX_SDK}/include)
4547
SET(UNTRUSTED_LIB_NAME uavalon-verify-ias-report)
4648
PROJECT(${UNTRUSTED_LIB_NAME} CXX)
4749

4850
pkg_check_modules (OPENSSL REQUIRED openssl>=1.1.1d)
4951

5052
ADD_LIBRARY(${UNTRUSTED_LIB_NAME} STATIC ${PROJECT_HEADERS} ${PROJECT_GENERATED_IAS_SOURCES} ${PROJECT_SOURCES})
5153

52-
TARGET_INCLUDE_DIRECTORIES(${UNTRUSTED_LIB_NAME} PRIVATE ${COMMON_PRIVATE_INCLUDE_DIRS})
54+
TARGET_INCLUDE_DIRECTORIES(${UNTRUSTED_LIB_NAME} PRIVATE ${COMMON_PRIVATE_INCLUDE_DIRS} ${SGX_SDK_INCLUDE})
5355

5456
TARGET_COMPILE_OPTIONS(${UNTRUSTED_LIB_NAME} PRIVATE ${COMMON_CXX_FLAGS} ${OPENSSL_CFLAGS})
5557

5658
TARGET_COMPILE_DEFINITIONS(${UNTRUSTED_LIB_NAME} PRIVATE "-D_UNTRUSTED_=1")
5759

60+
5861
################################################################################
5962
# Trusted Verify-Ias-Report Library
6063
################################################################################

common/cpp/verify_ias_report/ias_attestation_util.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,30 @@
1313
* limitations under the License.
1414
*/
1515

16-
#include <string>
1716
#include <stdio.h>
18-
#include <iostream>
1917
#include <string.h>
18+
#include <string>
19+
20+
#include <sgx_utils.h>
21+
#include <sgx_quote.h>
2022

2123
#include "ias_attestation_util.h"
2224
#include "verify-report.h"
2325
#include "tcf_error.h"
2426
#include "parson.h"
2527
#include "jsonvalue.h"
28+
#include "types.h"
2629

2730
bool verify_ias_report_signature(const std::string& signing_cert_pem,
28-
const std::string& ias_report,
29-
const std::string& ias_signature) {
31+
const std::string& ias_report,
32+
const std::string& ias_signature) {
33+
/* Verify IAS report signature
34+
* @param signing_cert_pem signing certificate
35+
* @param ias_report attestion report
36+
* @param ias_signature attestation report signature
37+
* Returns true if signature verification success
38+
* otherwise false
39+
*/
3040

3141
// Parse JSON serialized IAS report
3242
JsonValue report_parsed(json_parse_string(ias_report.c_str()));
@@ -54,3 +64,30 @@ bool verify_quote(const std::string& ias_report, int group_out_of_date_is_ok) {
5464
return quote_status;
5565
}
5666

67+
bool verify_mr_enclave_value(const std::string& enclave_quote_body,
68+
const std::string& mr_enclave) {
69+
/* Verify MR enclave in the attestation
70+
* report and compare with the value passed
71+
* @param enclave_quote_body Enclave quote body
72+
* @param mr_enclave MR enclave value in hex format
73+
* Return true if comparision matches otherwise false
74+
**/
75+
if (mr_enclave.size() != 0) {
76+
/* Extract ReportData and MR_ENCLAVE from isvEnclaveQuoteBody
77+
present in Verification Report */
78+
ByteArray quote_bytes = Base64EncodedStringToByteArray(
79+
enclave_quote_body.c_str());
80+
sgx_quote_t* quote_body = reinterpret_cast<sgx_quote_t*>(
81+
quote_bytes.data());
82+
sgx_report_body_t* report_body = &quote_body->report_body;
83+
sgx_measurement_t mr_enclave_from_report = *(&report_body->mr_enclave);
84+
ByteArray mr_enclave_bytes = HexEncodedStringToByteArray(mr_enclave);
85+
if (memcmp(mr_enclave_from_report.m, mr_enclave_bytes.data(),
86+
SGX_HASH_SIZE) == 0) {
87+
return true;
88+
}
89+
else {
90+
return false;
91+
}
92+
}
93+
}

common/cpp/verify_ias_report/ias_attestation_util.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717

1818
// Verifies signature of the message by extracting public key from certificate
1919
bool verify_ias_report_signature(const std::string& ias_attestation_signing_cert_pem,
20-
const std::string& ias_report,
21-
const std::string& ias_signature);
20+
const std::string& ias_report,
21+
const std::string& ias_signature);
2222

2323
// Verifies certificate against IAS CA certificate
2424
bool verify_quote(const std::string& ias_report, int group_out_of_date_is_ok);
2525

26+
// Verify MR enclave value
27+
bool verify_mr_enclave_value(const std::string& ias_report,
28+
const std::string& mr_enclave);

common/verify_report_utils/verify_report/verify_attestation_report.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
logger = logging.getLogger(__name__)
2121

2222

23-
def verify_attestation_report(enclave_info):
23+
def verify_attestation_report(enclave_info, mr_enclave=""):
2424
'''
2525
Function to verify quote status, signature of IAS attestation report
26+
and verify MR enclave value
2627
'''
2728

2829
verification_report = \
@@ -47,4 +48,17 @@ def verify_attestation_report(enclave_info):
4748
logger.error("Enclave IAS report signature verification failed")
4849
return report_sig_status
4950
logger.info("Enclave IAS report signature verification passed")
51+
52+
if mr_enclave != "":
53+
v_report = json.loads(
54+
enclave_info["proof_data"]["verification_report"])
55+
mr_check = verify_report_util.verify_mr_enclave_value(
56+
v_report["isvEnclaveQuoteBody"],
57+
mr_enclave)
58+
if mr_check is False:
59+
logger.error("MR enclave value check failed")
60+
return mr_check
61+
else:
62+
logger.info("MR enclave value check passed")
63+
5064
return True

docker/Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ FROM ubuntu:bionic as common_cpp_image
102102
RUN apt-get update \
103103
&& apt-get install -y -q \
104104
pkg-config \
105+
wget \
105106
cmake \
107+
libprotobuf-dev \
106108
make
107109

108110

@@ -112,6 +114,27 @@ COPY --from=openssl_image /usr/local/bin /usr/local/bin
112114
COPY --from=openssl_image /usr/local/include /usr/local/include
113115
COPY --from=openssl_image /usr/local/lib /usr/local/lib
114116

117+
# Intel SGX common library and SDK are installed in /opt/intel directory.
118+
# Installation of Intel SGX libsgx-common packages requires
119+
# /etc/init directory. In the Docker image this directory doesn't exist.
120+
# Hence creating /etc/init directory.
121+
RUN mkdir -p /opt/intel \
122+
&& mkdir -p /etc/init
123+
WORKDIR /opt/intel
124+
125+
# Install Intel SGX common library
126+
RUN wget https://download.01.org/intel-sgx/sgx-linux/2.7.1/distro/ubuntu18.04-server/libsgx-enclave-common_2.7.101.3-bionic1_amd64.deb \
127+
&& dpkg -i libsgx-enclave-common_2.7.101.3-bionic1_amd64.deb
128+
129+
# Install Intel SGX SDK
130+
RUN SGX_SDK_FILE=sgx_linux_x64_sdk_2.7.101.3.bin \
131+
&& wget --no-check-certificate https://download.01.org/intel-sgx/sgx-linux/2.7.1/distro/ubuntu18.04-server/$SGX_SDK_FILE \
132+
&& echo "yes" | bash ./$SGX_SDK_FILE \
133+
&& rm $SGX_SDK_FILE \
134+
&& echo ". /opt/intel/sgxsdk/environment" >> /etc/environment
135+
136+
ENV SGX_SDK=/opt/intel/sgxsdk
137+
115138
RUN ldconfig \
116139
&& ln -s /etc/ssl/certs/* /usr/local/ssl/certs/
117140

examples/apps/generic_client/base_generic_client.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def __init__(self):
4040
self._work_order_instance = None
4141
self._work_order_receipt_instance = None
4242

43-
def do_worker_verification(self, worker_obj):
43+
def do_worker_verification(self, worker_obj, mr_enclave):
4444
"""
4545
Do worker verification on proof data if it exists
4646
Proof data exists in SGX hardware mode.
@@ -60,8 +60,6 @@ def do_worker_verification(self, worker_obj):
6060
"Failed to verify worker encryption key signature")
6161
return False
6262

63-
# TODO Need to do verify MRENCLAVE value
64-
# in the attestation report
6563
if not worker_obj.proof_data:
6664
logging.info("Proof data is empty. " +
6765
"Skipping verification of attestation report")
@@ -76,7 +74,7 @@ def do_worker_verification(self, worker_obj):
7674

7775
logging.info("Perform verification of attestation report")
7876
verify_report_status = attestation_util.verify_attestation_report(
79-
enclave_info)
77+
enclave_info, mr_enclave)
8078
if verify_report_status is False:
8179
logging.error("Verification of enclave sign-up info failed")
8280
return False

examples/apps/generic_client/generic_client.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ def __init__(self, args):
110110
# requester signature for work order requests
111111
self._requester_signature = options.requester_signature
112112

113+
# MR enclave value
114+
if options.mr_enclave is None:
115+
self._mr_enclave = ""
116+
else:
117+
self._mr_enclave = options.mr_enclave
118+
113119
logging.info("******* Hyperledger Avalon Generic client *******")
114120

115121
# mode should be one of listing or registry (default)
@@ -182,6 +188,10 @@ def _parse_command_line(self, args):
182188
"-rs", "--requester_signature",
183189
help="Enable requester signature for work order requests",
184190
action="store_true")
191+
parser.add_argument(
192+
"-mr", "--mr_enclave",
193+
help='mr enclave value',
194+
type=str)
185195
options = parser.parse_args(args)
186196

187197
return options
@@ -238,6 +248,9 @@ def uri(self):
238248
def mode(self):
239249
return self._mode
240250

251+
def mr_enclave(self):
252+
return self._mr_enclave
253+
241254

242255
def Main(args=None):
243256
parser = GenericClient(args)
@@ -279,7 +292,10 @@ def Main(args=None):
279292
session_iv = crypto_utility.generate_iv()
280293

281294
# Do worker verification
282-
generic_client_obj.do_worker_verification(worker_obj)
295+
status = generic_client_obj.do_worker_verification(worker_obj,
296+
parser.mr_enclave())
297+
if status is False:
298+
sys.exit(-1)
283299

284300
logging.info("**********Worker details Updated with Worker ID" +
285301
"*********\n%s\n", worker_id)

0 commit comments

Comments
 (0)