diff --git a/.ci/ubuntu18.04.dockerfile b/.ci/ubuntu18.04.dockerfile index ec287b831b..4fc758d7f3 100644 --- a/.ci/ubuntu18.04.dockerfile +++ b/.ci/ubuntu18.04.dockerfile @@ -8,6 +8,7 @@ RUN apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install -y \ bison \ build-essential \ cargo \ + cmake \ curl \ flex \ gawk \ diff --git a/.ci/ubuntu20.04.dockerfile b/.ci/ubuntu20.04.dockerfile index fef644df87..2f772327df 100644 --- a/.ci/ubuntu20.04.dockerfile +++ b/.ci/ubuntu20.04.dockerfile @@ -8,6 +8,7 @@ RUN apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install -y \ build-essential \ cargo \ clang \ + cmake \ curl \ flex \ gawk \ diff --git a/CI-Examples/ra-tls-mbedtls/src/server.c b/CI-Examples/ra-tls-mbedtls/src/server.c index d5c63ae87c..c9e4a2facb 100644 --- a/CI-Examples/ra-tls-mbedtls/src/server.c +++ b/CI-Examples/ra-tls-mbedtls/src/server.c @@ -184,25 +184,42 @@ int main(int argc, char** argv) { return 1; } - /* user asks to maliciously modify the embedded SGX quote (for testing purposes) */ + /* user asks to maliciously modify the embedded SGX quote (for testing purposes); we + * have two quotes currently (with legacy OID and with standard TCG DICE OID), so we + * modify them both */ mbedtls_printf(" . Maliciously modifying SGX quote embedded in RA-TLS cert..."); fflush(stdout); - uint8_t oid[] = {0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF8, 0x4D, 0x8A, 0x39, 0x06}; - uint8_t* p = memmem(srvcert.v3_ext.p, srvcert.v3_ext.len, oid, sizeof(oid)); - if (!p) { - mbedtls_printf(" failed\n ! No embedded SGX quote found\n\n"); - goto exit; + uint8_t legacy_oid[] = {0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF8, 0x4D, 0x8A, 0x39, + 0x06}; + uint8_t standard_oid[] = { 0x06, 0x06, 0x67, 0x81, 0x05, 0x05, 0x04, 0x09 }; + struct { + uint8_t* oid; + size_t size; + size_t offset; + } oids[2] = { + { .oid = legacy_oid, .size = sizeof(legacy_oid), .offset = 5}, + { .oid = standard_oid, .size = sizeof(standard_oid), .offset = 10}, + }; + + for (size_t i = 0; i < 2; i++) { + uint8_t* p = memmem(srvcert.v3_ext.p, srvcert.v3_ext.len, oids[i].oid, + oids[i].size); + if (!p) { + mbedtls_printf(" failed\n ! No embedded SGX quote found\n\n"); + goto exit; + } + + p += oids[i].size; + p += oids[i].offset; /* jump somewhere in the middle of the SGX quote */ + if (p + sizeof(MALICIOUS_STR) > srvcert.v3_ext.p + srvcert.v3_ext.len) { + mbedtls_printf(" failed\n ! Size of embedded SGX quote is too small\n\n"); + goto exit; + } + + memcpy(p, MALICIOUS_STR, sizeof(MALICIOUS_STR)); } - p += sizeof(oid); - p += 5; /* jump somewhere in the middle of the SGX quote */ - if (p + sizeof(MALICIOUS_STR) > srvcert.v3_ext.p + srvcert.v3_ext.len) { - mbedtls_printf(" failed\n ! Size of embedded SGX quote is too small\n\n"); - goto exit; - } - - memcpy(p, MALICIOUS_STR, sizeof(MALICIOUS_STR)); mbedtls_printf(" ok\n"); } } else { diff --git a/Documentation/attestation.rst b/Documentation/attestation.rst index 8b5441bbf5..5d43a01e17 100644 --- a/Documentation/attestation.rst +++ b/Documentation/attestation.rst @@ -248,21 +248,45 @@ information (SGX quote). The additional information allows the remote user (verifier) of the certificate to verify that it is indeed communicating with an SGX enclave (attester). -.. image:: ./img/ratls.svg - :target: ./img/ratls.svg - :alt: Figure: The X.509 certificate generated by RA-TLS +.. image:: ./img/ratls-interoperable.svg + :target: ./img/ratls-interoperable.svg + :alt: Figure: The X.509 certificate generated by RA-TLS (standardized) The diagram above shows the standard X.509 certificate generated by RA-TLS (the diagram shows the DCAP based RA-TLS certificate, but the EPID based RA-TLS certificate is conceptually similar). This certificate is self-signed because the actual chain of trust is stored in the Intel SGX certificates embedded in -the SGX quote. The most important concept behind the RA-TLS certificate is that -it embeds the SGX quote (in one of the unused X.509 extension fields), which in -turn embeds the SGX report and the complete Intel SGX certificate chain. -Therefore, the RA-TLS certificate contains all the SGX-relevant information. -Also, notice how the SGX report's REPORTDATA field contains the secure hash of -the ephemeral public key generated by the enclavized application -- this is how -this RA-TLS certificate is tied to the enclavized application that generated it. +the SGX quote. + +The most important concept behind the RA-TLS certificate is that it embeds the +SGX quote (in the standardized X.509 extension field with the TCG DICE "tagged +evidence" OID), which in turn embeds the SGX report and the complete Intel SGX +certificate chain. In addition to the SGX quote, the certificate also contains +the so-called evidence claims, with the most important one being the "pubkey" +claim that contains the ephemeral public key (in DER format) generated by the +enclavized application. For reasons of standardization, the OID object and all +its sub-objects are encoded in the CBOR data format. + +Notice how the SGX report's REPORTDATA field contains the secure hash of the +complete claims buffer. This is how the RA-TLS certificate is tied to the +enclavized application that generated it (through the claims buffer that +contains the enclave-generated public key). In the end, the RA-TLS certificate +contains all the SGX-relevant information. + +.. image:: ./img/ratls.svg + :target: ./img/ratls.svg + :alt: Figure: The X.509 certificate generated by RA-TLS (legacy) + +The diagram above shows the non-standard X.509 certificate generated by RA-TLS. +This format, with a non-standard X.509 extension field (and a dummy OID), was +developed prior to the "Interoperable RA-TLS" specification, and is deprecated. +One can see that the non-standard OID directly embeds the SGX quote, doesn't +have the concept of claims and doesn't use the CBOR data format. + +Gramine generates RA-TLS certificates that contain both the new standard OID and +the legacy non-standard OID, for backward compatibility. In the future, legacy +OID will be dropped, and only the new standard OID will be put in the X.509 +certificates generated by Gramine. RA-TLS is shipped as three libraries: ``ra_tls_attest.so``, EPID based ``ra_tls_verify_epid.so`` and DCAP/ECDSA based ``ra_tls_verify_dcap.so``. diff --git a/Documentation/devel/building.rst b/Documentation/devel/building.rst index 74dc07a2af..149464846e 100644 --- a/Documentation/devel/building.rst +++ b/Documentation/devel/building.rst @@ -71,7 +71,7 @@ running, and Intel SGX SDK/PSW/DCAP must be installed. """""""""""""""""""" Run the following commands on Ubuntu to install SGX-related dependencies:: - sudo apt-get install -y libprotobuf-c-dev protobuf-c-compiler \ + sudo apt-get install -y cmake libprotobuf-c-dev protobuf-c-compiler \ protobuf-compiler python3-cryptography python3-pip python3-protobuf 2. Install Linux kernel with patched FSGSBASE diff --git a/Documentation/img/ratls-interoperable.svg b/Documentation/img/ratls-interoperable.svg new file mode 100644 index 0000000000..234746e54e --- /dev/null +++ b/Documentation/img/ratls-interoperable.svg @@ -0,0 +1 @@ +X.509 certSUBJECT = “CN=RATLS,O=…”ISSUER = “CN=RATLS,O=…”TCG DICE tagged evidence OIDCBOR tagged object = TBDCBOR array = []Claims (as CBOR bstr)pubkey” = PK (as CBOR bstr)… more claims in future …X.509 public key (PK), in DER formatRA-TLS certificate(DCAP-based,TCG DICE format)Self-signed certificateMust verify against expectedCompare CBOR-bstrclaims against this hashMust verify against Intel PCS provided attestation certificatesSGX Quote (as CBOR bstr)VERSION = 1..Intel SGX certs = SGX Report (EREPORT)REPORTDATA = sha256(claims)… measurements …Compare cert PK against this oneRegistered IANA OID: 2.23.133.5.4.9Registered IANA CBOR tag: TBDClaims is a CBOR map, serialized as CBOR bstr diff --git a/meson.build b/meson.build index 7d6e93b75f..d17f8cf121 100644 --- a/meson.build +++ b/meson.build @@ -263,6 +263,8 @@ if sgx protobuf_dep = dependency('libprotobuf-c') + libcbor_dep = subproject('libcbor-0.9.0').get_variable('libcbor_dep') + if dcap sgx_dcap_quoteverify_dep = cc.find_library('sgx_dcap_quoteverify') endif diff --git a/subprojects/.gitignore b/subprojects/.gitignore index a2c9535aaa..c5385662dd 100644 --- a/subprojects/.gitignore +++ b/subprojects/.gitignore @@ -4,6 +4,7 @@ /curl-*/ /gcc-*/ /glibc-*/ +/libcbor-*/ /mbedtls-*/ /musl-*/ /tomlc99-*/ diff --git a/subprojects/libcbor-0.9.0.wrap b/subprojects/libcbor-0.9.0.wrap new file mode 100644 index 0000000000..56a72cb502 --- /dev/null +++ b/subprojects/libcbor-0.9.0.wrap @@ -0,0 +1,7 @@ +[wrap-file] +directory = libcbor-0.9.0 +source_url = https://github.com/PJK/libcbor/archive/refs/tags/v0.9.0.tar.gz +source_fallback_url = https://packages.gramineproject.io/distfiles/libcbor-v0.9.0.tar.gz +source_filename = libcbor-0.9.0.tar.gz +source_hash = da81e4f9333e0086d4e2745183c7052f04ecc4dbcffcf910029df24f103c15d1 +patch_directory = libcbor diff --git a/subprojects/packagefiles/libcbor/compile.sh b/subprojects/packagefiles/libcbor/compile.sh new file mode 100644 index 0000000000..fc683c5e01 --- /dev/null +++ b/subprojects/packagefiles/libcbor/compile.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +set -e + +log() { + echo "libcbor (static): $*" +} + +CURRENT_SOURCE_DIR="$1" +CURRENT_BUILD_DIR="$2" +PRIVATE_DIR="$3" + +BUILD_LOG=$(realpath "$CURRENT_BUILD_DIR/libcbor-build.log") +rm -f "$BUILD_LOG" + +log "see $BUILD_LOG for full build log" + +log "preparing sources..." + +rm -rf "$PRIVATE_DIR" +cp -ar "$CURRENT_SOURCE_DIR" "$PRIVATE_DIR" + +( + cd "$PRIVATE_DIR" + + log "running cmake..." + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -DCMAKE_INSTALL_PREFIX="$CURRENT_BUILD_DIR" \ + . >>"$BUILD_LOG" 2>&1 + + log "running make..." + make -j"$(nproc)" >>"$BUILD_LOG" 2>&1 + make install >>"$BUILD_LOG" 2>&1 +) + +cp -ar "$CURRENT_BUILD_DIR"/include/. "$CURRENT_BUILD_DIR" +cp -ar "$CURRENT_BUILD_DIR"/lib/. "$CURRENT_BUILD_DIR" + +log "ls -la $CURRENT_BUILD_DIR" +ls -la $CURRENT_BUILD_DIR + +log "done" diff --git a/subprojects/packagefiles/libcbor/meson.build b/subprojects/packagefiles/libcbor/meson.build new file mode 100644 index 0000000000..69804926d6 --- /dev/null +++ b/subprojects/packagefiles/libcbor/meson.build @@ -0,0 +1,37 @@ +project('libcbor', 'c', version: '0.9.0') + +fs = import('fs') + +# NOTE: This is custom_target, because CMake integration in Meson doesn't work correctly with PIC +# static libraries, see https://github.com/mesonbuild/meson/issues/10764. +libcbor_lib = custom_target('libcbor', + command: [ + find_program('compile.sh'), + '@CURRENT_SOURCE_DIR@', + meson.current_build_dir(), + '@PRIVATE_DIR@', + ], + + input: 'CMakeLists.txt', + output: [ + 'libcbor.a', + 'cbor.h', + ], + + console: true, + install: false, +) + +# We can't use `include_directories('include')` because the `include/` dir is generated in the +# custom target above, but Meson checks for existence of the dir *before* running the target +libcbor_inc = include_directories('.') + +libcbor_dep = declare_dependency( + link_with: libcbor_lib[0], + # HACK: Use the generated "cbor.h" file and propagate it as part of the RA-TLS build dependency + # to enforce compile order, i.e., to make sure libcbor headers are ready before RA-TLS sources + # start compiling. + sources: libcbor_lib[1], + include_directories: libcbor_inc, + compile_args: '-Wno-strict-prototypes', +) diff --git a/tools/sgx/ra-tls/meson.build b/tools/sgx/ra-tls/meson.build index b57a459204..8b714b6ba9 100644 --- a/tools/sgx/ra-tls/meson.build +++ b/tools/sgx/ra-tls/meson.build @@ -13,6 +13,7 @@ libra_tls_attest = shared_library('ra_tls_attest', c_args: ra_tls_args, include_directories: pal_sgx_inc, # this is only for `sgx_arch.h` and `sgx_attest.h` dependencies: [ + libcbor_dep, mbedtls_static_dep, ], install: true, @@ -31,8 +32,9 @@ libra_tls_verify_epid = shared_library('ra_tls_verify_epid', c_args: ra_tls_args, include_directories: pal_sgx_inc, dependencies: [ - sgx_util_dep, + libcbor_dep, mbedtls_static_dep, + sgx_util_dep, ], install: true, install_rpath: join_paths(get_option('prefix'), get_option('libdir')), @@ -52,6 +54,7 @@ libsecret_prov_attest = shared_library('secret_prov_attest', c_args: ra_tls_args, include_directories: pal_sgx_inc, dependencies: [ + libcbor_dep, mbedtls_static_dep, sgx_util_dep, ], @@ -74,9 +77,10 @@ libsecret_prov_verify_epid = shared_library('secret_prov_verify_epid', c_args: ra_tls_args, include_directories: pal_sgx_inc, dependencies: [ - threads_dep, - sgx_util_dep, + libcbor_dep, mbedtls_static_dep, + sgx_util_dep, + threads_dep, ], install: true, install_rpath: join_paths(get_option('prefix'), get_option('libdir')), @@ -95,9 +99,10 @@ if dcap c_args: ra_tls_args, include_directories: pal_sgx_inc, dependencies: [ + libcbor_dep, + mbedtls_static_dep, sgx_dcap_quoteverify_dep, sgx_util_dep, - mbedtls_static_dep, ], install: true, install_rpath: join_paths(get_option('prefix'), get_option('libdir')), @@ -116,9 +121,10 @@ if dcap c_args: ra_tls_args, include_directories: pal_sgx_inc, dependencies: [ + libcbor_dep, + mbedtls_static_dep, sgx_dcap_quoteverify_dep, sgx_util_dep, - mbedtls_static_dep, ], install: true, install_rpath: join_paths(get_option('prefix'), get_option('libdir')), @@ -139,10 +145,11 @@ if dcap c_args: ra_tls_args, include_directories: pal_sgx_inc, dependencies: [ - threads_dep, + libcbor_dep, + mbedtls_static_dep, sgx_dcap_quoteverify_dep, sgx_util_dep, - mbedtls_static_dep, + threads_dep, ], install: true, install_rpath: join_paths(get_option('prefix'), get_option('libdir')), diff --git a/tools/sgx/ra-tls/ra_tls.h b/tools/sgx/ra-tls/ra_tls.h index 13ae00d3a3..f8af6930a4 100644 --- a/tools/sgx/ra-tls/ra_tls.h +++ b/tools/sgx/ra-tls/ra_tls.h @@ -30,11 +30,30 @@ #define PUB_KEY_SIZE_MAX 128 /* enough for the only currently supported algo (ECDSA-384) */ #define IAS_REQUEST_NONCE_LEN 32 -#define OID(N) \ - { 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF8, 0x4D, 0x8A, 0x39, (N) } -static const uint8_t g_quote_oid[] = OID(0x06); +/* below OID is actually wrong: it shouldn't have the first two bytes (0x06 0x09) because they + * represent the ASN.1 Type (6 = OBJECT IDENTIFIER) and ASN.1 Length (9 bytes); we don't modify it + * because it is non-standard anyway and we don't want to break backwards-compatibility */ +#define NON_STANDARD_INTEL_SGX_QUOTE_OID \ + { 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF8, 0x4D, 0x8A, 0x39, 0x06 } +static const uint8_t g_quote_oid[] = NON_STANDARD_INTEL_SGX_QUOTE_OID; static const size_t g_quote_oid_size = sizeof(g_quote_oid); +/* standard TCG DICE "tagged evidence" OID (2.23.133.5.4.9) */ +#define TCG_DICE_TAGGED_EVIDENCE_OID { 0x67, 0x81, 0x05, 0x05, 0x04, 0x09 } +#define TCG_DICE_TAGGED_EVIDENCE_OID_RAW { 0x06, 0x06, 0x67, 0x81, 0x05, 0x05, 0x04, 0x09 } +static const uint8_t g_evidence_oid[] = TCG_DICE_TAGGED_EVIDENCE_OID; +static const size_t g_evidence_oid_size = sizeof(g_evidence_oid); +static const uint8_t g_evidence_oid_raw[] = TCG_DICE_TAGGED_EVIDENCE_OID_RAW; +static const size_t g_evidence_oid_raw_size = sizeof(g_evidence_oid_raw); + +#define TCG_DICE_TAGGED_EVIDENCE_CBOR_TAG 0x1A75 /* FIXME: proper IANA tag once registered */ + +/* hash IDs per IANA: https://www.iana.org/assignments/named-information/named-information.xhtml */ +#define IANA_NAMED_INFO_HASH_ALG_REGISTRY_RESERVED 0 +#define IANA_NAMED_INFO_HASH_ALG_REGISTRY_SHA256 1 +#define IANA_NAMED_INFO_HASH_ALG_REGISTRY_SHA384 7 +#define IANA_NAMED_INFO_HASH_ALG_REGISTRY_SHA512 8 + typedef int (*verify_measurements_cb_t)(const char* mrenclave, const char* mrsigner, const char* isv_prod_id, const char* isv_svn); @@ -49,7 +68,7 @@ __attribute__ ((visibility("hidden"))) int cmp_crt_pk_against_quote_report_data(mbedtls_x509_crt* crt, sgx_quote_t* quote); __attribute__ ((visibility("hidden"))) -int extract_quote_and_verify_pubkey(mbedtls_x509_crt* crt, sgx_quote_t** out_quote, +int extract_quote_and_verify_claims(mbedtls_x509_crt* crt, sgx_quote_t** out_quote, size_t* out_quote_size); __attribute__ ((visibility("hidden"))) diff --git a/tools/sgx/ra-tls/ra_tls_attest.c b/tools/sgx/ra-tls/ra_tls_attest.c index 0ce47b7738..a7c3abe989 100644 --- a/tools/sgx/ra-tls/ra_tls_attest.c +++ b/tools/sgx/ra-tls/ra_tls_attest.c @@ -22,6 +22,8 @@ #include #include +#include + #include #include #include @@ -67,8 +69,10 @@ static ssize_t rw_file(const char* path, uint8_t* buf, size_t len, bool do_write return ret < 0 ? ret : bytes; } -/*! given public key \p pk, generate an RA-TLS certificate \p writecrt with \p quote embedded */ +/*! given public key \p pk, generate an RA-TLS certificate \p writecrt with \p quote (legacy format) + * and \p evidence (new standard format) embedded */ static int generate_x509(mbedtls_pk_context* pk, const uint8_t* quote, size_t quote_size, + const uint8_t* evidence, size_t evidence_size, mbedtls_x509write_cert* writecrt) { int ret; char* cert_timestamp_not_before = NULL; @@ -133,12 +137,21 @@ static int generate_x509(mbedtls_pk_context* pk, const uint8_t* quote, size_t qu if (ret < 0) goto out; - /* finally, embed the quote into the generated certificate (as X.509 extension) */ + /* embed the SGX quote into the generated certificate (as X.509 extension) in two formats: + * - legacy non-standard "SGX quote" OID (used from Gramine v1.0) + * - new standard TCG DICE "tagged evidence" OID (2.23.133.5.4.9) + */ ret = mbedtls_x509write_crt_set_extension(writecrt, (const char*)g_quote_oid, g_quote_oid_size, /*critical=*/0, quote, quote_size); if (ret < 0) goto out; + ret = mbedtls_x509write_crt_set_extension(writecrt, (const char*)g_evidence_oid, + g_evidence_oid_size, /*critical=*/0, evidence, + evidence_size); + if (ret < 0) + goto out; + ret = 0; out: free(cert_timestamp_not_before); @@ -162,8 +175,9 @@ static int sha256_over_pk(mbedtls_pk_context* pk, uint8_t* sha) { return mbedtls_sha256(pk_der, pk_der_size_byte, sha, /*is224=*/0); } -/*! given public key \p pk, generate an RA-TLS certificate \p writecrt */ -static int create_x509(mbedtls_pk_context* pk, mbedtls_x509write_cert* writecrt) { +/*! generate SGX quote with user_report_data equal to SHA256 hash over \p pk (legacy format) */ +static int generate_quote_with_pk_hash(mbedtls_pk_context* pk, uint8_t** out_quote, + size_t* out_quote_size) { sgx_report_data_t user_report_data = {0}; int ret = sha256_over_pk(pk, user_report_data.d); if (ret < 0) @@ -185,9 +199,310 @@ static int create_x509(mbedtls_pk_context* pk, mbedtls_x509write_cert* writecrt) return MBEDTLS_ERR_X509_FILE_IO_ERROR; } - ret = generate_x509(pk, quote, quote_size, writecrt); + *out_quote = quote; + *out_quote_size = (size_t)quote_size; + return 0; +} + +/*! create CBOR bstr from SHA256 hash of public key \p pk and copy it into \p out_cbor_bstr */ +static int cbor_bstr_from_pk_sha256(mbedtls_pk_context* pk, cbor_item_t** out_cbor_bstr) { + uint8_t sha256[SHA256_DIGEST_SIZE] = {0}; + int ret = sha256_over_pk(pk, sha256); + if (ret < 0) + return ret; + + cbor_item_t* cbor_bstr = cbor_build_bytestring(sha256, sizeof(sha256)); + if (!cbor_bstr) + return MBEDTLS_ERR_X509_ALLOC_FAILED; + + *out_cbor_bstr = cbor_bstr; + return 0; +} + +/*! generate hash-entry -- CBOR array with [ hash-alg-id, hash-value -- hash of pubkey ] */ +static int generate_serialized_hash_entry(mbedtls_pk_context* pk, uint8_t** out_hash_entry_buf, + size_t* out_hash_entry_buf_size) { + /* the hash-entry array as defined in Concise Software Identification Tags (CoSWID) */ + cbor_item_t* cbor_hash_entry = cbor_new_definite_array(2); + if (!cbor_hash_entry) + return MBEDTLS_ERR_X509_ALLOC_FAILED; + + /* RA-TLS always generates SHA256 hash over pubkey */ + cbor_item_t* cbor_hash_alg_id = cbor_build_uint8(IANA_NAMED_INFO_HASH_ALG_REGISTRY_SHA256); + if (!cbor_hash_alg_id) { + cbor_decref(&cbor_hash_entry); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + cbor_item_t* cbor_hash_value; + int ret = cbor_bstr_from_pk_sha256(pk, &cbor_hash_value); + if (ret < 0) { + cbor_decref(&cbor_hash_alg_id); + cbor_decref(&cbor_hash_entry); + return ret; + } + + int bool_ret = cbor_array_push(cbor_hash_entry, cbor_hash_alg_id); + if (!bool_ret) { + cbor_decref(&cbor_hash_value); + cbor_decref(&cbor_hash_alg_id); + cbor_decref(&cbor_hash_entry); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + bool_ret = cbor_array_push(cbor_hash_entry, cbor_hash_value); + if (!bool_ret) { + cbor_decref(&cbor_hash_value); + cbor_decref(&cbor_hash_alg_id); + cbor_decref(&cbor_hash_entry); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + /* cbor_hash_entry took ownership of hash_alg_id and hash_value cbor items */ + cbor_decref(&cbor_hash_alg_id); + cbor_decref(&cbor_hash_value); + + uint8_t* hash_entry_buf; + size_t hash_entry_buf_size; + cbor_serialize_alloc(cbor_hash_entry, &hash_entry_buf, &hash_entry_buf_size); + + cbor_decref(&cbor_hash_entry); + + if (!hash_entry_buf) + return MBEDTLS_ERR_X509_ALLOC_FAILED; + + *out_hash_entry_buf = hash_entry_buf; + *out_hash_entry_buf_size = hash_entry_buf_size; + return 0; +} + +/*! generate claims -- CBOR map with { "pubkey-hash" = } */ +static int generate_serialized_claims(mbedtls_pk_context* pk, uint8_t** out_claims_buf, + size_t* out_claims_buf_size) { + cbor_item_t* cbor_claims = cbor_new_definite_map(1); + if (!cbor_claims) + return MBEDTLS_ERR_X509_ALLOC_FAILED; + + cbor_item_t* cbor_pubkey_hash_key = cbor_build_string("pubkey-hash"); + if (!cbor_pubkey_hash_key) { + cbor_decref(&cbor_claims); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + uint8_t* hash_entry_buf; + size_t hash_entry_buf_size; + int ret = generate_serialized_hash_entry(pk, &hash_entry_buf, &hash_entry_buf_size); + if (ret < 0) { + cbor_decref(&cbor_pubkey_hash_key); + cbor_decref(&cbor_claims); + return ret; + } + + cbor_item_t* cbor_pubkey_hash_val = cbor_build_bytestring(hash_entry_buf, hash_entry_buf_size); + + free(hash_entry_buf); + + if (!cbor_pubkey_hash_val) { + cbor_decref(&cbor_pubkey_hash_key); + cbor_decref(&cbor_claims); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + struct cbor_pair cbor_pubkey_hash_pair = { .key = cbor_pubkey_hash_key, + .value = cbor_pubkey_hash_val }; + bool bool_ret = cbor_map_add(cbor_claims, cbor_pubkey_hash_pair); + if (!bool_ret) { + cbor_decref(&cbor_pubkey_hash_val); + cbor_decref(&cbor_pubkey_hash_key); + cbor_decref(&cbor_claims); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + uint8_t* claims_buf; + size_t claims_buf_size; + cbor_serialize_alloc(cbor_claims, &claims_buf, &claims_buf_size); + + cbor_decref(&cbor_pubkey_hash_val); + cbor_decref(&cbor_pubkey_hash_key); + cbor_decref(&cbor_claims); + + if (!claims_buf) + return MBEDTLS_ERR_X509_ALLOC_FAILED; + + *out_claims_buf = claims_buf; + *out_claims_buf_size = claims_buf_size; + return 0; +} + +/*! generate evidence -- CBOR tag with CBOR array of CBOR bstrs: [ quote, claims ] */ +static int generate_serialized_evidence(uint8_t* quote, size_t quote_size, uint8_t* claims, + size_t claims_size, uint8_t** out_evidence_buf, + size_t* out_evidence_buf_size) { + cbor_item_t* cbor_evidence = cbor_new_definite_array(2); + if (!cbor_evidence) + return MBEDTLS_ERR_X509_ALLOC_FAILED; + + cbor_item_t* cbor_quote = cbor_build_bytestring(quote, quote_size); + if (!cbor_quote) { + cbor_decref(&cbor_evidence); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + cbor_item_t* cbor_claims = cbor_build_bytestring(claims, claims_size); + if (!cbor_claims) { + cbor_decref(&cbor_quote); + cbor_decref(&cbor_evidence); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + int bool_ret = cbor_array_push(cbor_evidence, cbor_quote); + if (!bool_ret) { + cbor_decref(&cbor_claims); + cbor_decref(&cbor_quote); + cbor_decref(&cbor_evidence); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + bool_ret = cbor_array_push(cbor_evidence, cbor_claims); + if (!bool_ret) { + cbor_decref(&cbor_claims); + cbor_decref(&cbor_quote); + cbor_decref(&cbor_evidence); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + /* cbor_evidence took ownership of quote and claims cbor bstrs */ + cbor_decref(&cbor_claims); + cbor_decref(&cbor_quote); + + cbor_item_t* cbor_tagged_evidence = cbor_new_tag(TCG_DICE_TAGGED_EVIDENCE_CBOR_TAG); + if (!cbor_tagged_evidence) { + cbor_decref(&cbor_evidence); + return MBEDTLS_ERR_X509_ALLOC_FAILED; + } + + cbor_tag_set_item(cbor_tagged_evidence, cbor_evidence); + + uint8_t* evidence_buf; + size_t evidence_buf_size; + cbor_serialize_alloc(cbor_tagged_evidence, &evidence_buf, &evidence_buf_size); + cbor_decref(&cbor_evidence); + cbor_decref(&cbor_tagged_evidence); + + if (!evidence_buf) + return MBEDTLS_ERR_X509_ALLOC_FAILED; + + *out_evidence_buf = evidence_buf; + *out_evidence_buf_size = evidence_buf_size; + return 0; +} + +/*! generate SGX-quote evidence with \p pk as one of the embedded claims (standard format) */ +static int generate_evidence_with_claims(mbedtls_pk_context* pk, uint8_t** out_evidence, + size_t* out_evidence_size) { + /* + * SGX-quote evidence has the following serialized-CBOR format: + * + * CBOR object (major type 6, new CBOR tag for "ECDSA SGX Quotes") -> + * CBOR array -> + * [ + * 0: CBOR bstr (SGX quote with user_report_data = hash(serialized-cbor-map of claims)), + * 1: CBOR bstr (serialized-cbor-map of claims) + * ] + * + * where "serialized-cbor-map of claims" is as follows: + * + * CBOR map -> + * { + * "pubkey-hash" (req) : CBOR bstr (serialized-cbor-array hash-entry), + * "nonce" (opt) : CBOR bstr (arbitrary-sized nonce for per-session freshness) + * } + * + * where "serialized-cbor-array hash-entry" is as follows: + * + * CBOR array -> + * [ + * 0: CBOR uint (hash-alg-id), + * 1: CBOR bstr (hash of DER-formatted "SubjectPublicKeyInfo" field as CBOR bstr) + * ] + * + * For hash-alg-id values, see + * https://www.iana.org/assignments/named-information/named-information.xhtml + */ + uint8_t* claims = NULL; + uint8_t* quote = NULL; + uint8_t* evidence = NULL; + + size_t claims_size; + int ret = generate_serialized_claims(pk, &claims, &claims_size); + if (ret < 0) + goto out; + + sgx_report_data_t user_report_data = {0}; + ret = mbedtls_sha256(claims, claims_size, user_report_data.d, /*is224=*/0); + if (ret < 0) + goto out; + + ssize_t written = rw_file("/dev/attestation/user_report_data", user_report_data.d, + sizeof(user_report_data.d), /*do_write=*/true); + if (written != sizeof(user_report_data)) { + ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; + goto out; + } + + quote = malloc(SGX_QUOTE_MAX_SIZE); + if (!quote) { + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + goto out; + } + + ssize_t quote_size = rw_file("/dev/attestation/quote", quote, SGX_QUOTE_MAX_SIZE, + /*do_write=*/false); + if (quote_size < 0) { + ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; + goto out; + } + + size_t evidence_size; + ret = generate_serialized_evidence(quote, quote_size, claims, claims_size, &evidence, + &evidence_size); + if (ret < 0) + goto out; + + *out_evidence = evidence; + *out_evidence_size = (size_t)evidence_size; + ret = 0; +out: + free(quote); + free(claims); + return ret; +} + +/*! given public key \p pk, generate an RA-TLS certificate \p writecrt */ +static int create_x509(mbedtls_pk_context* pk, mbedtls_x509write_cert* writecrt) { + int ret; + + /* put both "legacy Gramine" OID with plain SGX quote as well as standardized TCG DICE "tagged + * evidence" OID with CBOR-formatted SGX quote into RA-TLS X.509 cert */ + uint8_t* quote = NULL; + uint8_t* evidence = NULL; + + /* TODO: this legacy OID with plain SGX quote should be removed at some point */ + size_t quote_size; + ret = generate_quote_with_pk_hash(pk, "e, "e_size); + if (ret < 0) + goto out; + + size_t evidence_size; + ret = generate_evidence_with_claims(pk, &evidence, &evidence_size); + if (ret < 0) + goto out; + + ret = generate_x509(pk, quote, quote_size, evidence, evidence_size, writecrt); +out: free(quote); + free(evidence); return ret; } diff --git a/tools/sgx/ra-tls/ra_tls_verify_common.c b/tools/sgx/ra-tls/ra_tls_verify_common.c index d8afd8bbd7..d999a1e036 100644 --- a/tools/sgx/ra-tls/ra_tls_verify_common.c +++ b/tools/sgx/ra-tls/ra_tls_verify_common.c @@ -13,6 +13,8 @@ #include #include +#include + #include #include #include @@ -170,32 +172,34 @@ static int find_oid(const uint8_t* exts, size_t exts_size, const uint8_t* oid, s return 0; } -/*! calculate sha256 over public key from \p crt and copy it into \p sha */ -static int sha256_over_crt_pk(mbedtls_x509_crt* crt, uint8_t* sha) { +/*! fill buffer \p pk_der with DER-formatted public key from \p crt */ +static int fill_crt_pk_der(mbedtls_x509_crt* crt, uint8_t* pk_der, size_t* pk_der_size) { mbedtls_ecp_keypair* key = mbedtls_pk_ec(crt->pk); if (key == NULL || key->MBEDTLS_PRIVATE(grp).id != MBEDTLS_ECP_DP_SECP384R1) { return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } - uint8_t pk_der[PUB_KEY_SIZE_MAX] = {0}; - /* below function writes data at the end of the buffer */ - int pk_der_size_byte = mbedtls_pk_write_pubkey_der(&crt->pk, pk_der, sizeof(pk_der)); - if (pk_der_size_byte < 0) - return pk_der_size_byte; + int pk_der_size_int = mbedtls_pk_write_pubkey_der(&crt->pk, pk_der, *pk_der_size); + if (pk_der_size_int < 0) + return pk_der_size_int; /* move the data to the beginning of the buffer, to avoid pointer arithmetic later */ - memmove(pk_der, pk_der + PUB_KEY_SIZE_MAX - pk_der_size_byte, pk_der_size_byte); - - return mbedtls_sha256(pk_der, pk_der_size_byte, sha, /*is224=*/0); + memmove(pk_der, pk_der + *pk_der_size - pk_der_size_int, pk_der_size_int); + *pk_der_size = (size_t)pk_der_size_int; + return 0; } -/*! compares if report_data from \quote corresponds to sha256 of public key in \p crt */ +/*! compares if report_data from \p quote corresponds to sha256 of public key in \p crt */ int cmp_crt_pk_against_quote_report_data(mbedtls_x509_crt* crt, sgx_quote_t* quote) { - int ret; + uint8_t pk_der[PUB_KEY_SIZE_MAX] = {0}; + size_t pk_der_size = sizeof(pk_der); + int ret = fill_crt_pk_der(crt, pk_der, &pk_der_size); + if (ret < 0) + return ret; uint8_t sha[SHA256_DIGEST_SIZE]; - ret = sha256_over_crt_pk(crt, sha); + ret = mbedtls_sha256(pk_der, pk_der_size, sha, /*is224=*/0); if (ret < 0) return ret; @@ -206,10 +210,249 @@ int cmp_crt_pk_against_quote_report_data(mbedtls_x509_crt* crt, sgx_quote_t* quo return 0; } -int extract_quote_and_verify_pubkey(mbedtls_x509_crt* crt, sgx_quote_t** out_quote, - size_t* out_quote_size) { +/*! compares if CBOR array \p cbor_hash_entry from claims corresponds to public key in \p crt */ +static int cmp_crt_pk_against_cbor_claim_hash_entry(mbedtls_x509_crt* crt, + cbor_item_t* cbor_hash_entry) { + uint8_t pk_der[PUB_KEY_SIZE_MAX] = {0}; + size_t pk_der_size = sizeof(pk_der); + int ret = fill_crt_pk_der(crt, pk_der, &pk_der_size); + if (ret < 0) + return ret; + + if (!cbor_isa_array(cbor_hash_entry) || !cbor_array_is_definite(cbor_hash_entry) + || cbor_array_size(cbor_hash_entry) != 2) { + return MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + } + + cbor_item_t* cbor_hash_alg_id = NULL; + cbor_item_t* cbor_hash_value = NULL; + + cbor_hash_alg_id = cbor_array_get(cbor_hash_entry, /*index=*/0); + if (!cbor_hash_alg_id || !cbor_isa_uint(cbor_hash_alg_id)) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + cbor_hash_value = cbor_array_get(cbor_hash_entry, /*index=*/1); + if (!cbor_hash_value || !cbor_isa_bytestring(cbor_hash_value) + || !cbor_bytestring_is_definite(cbor_hash_value)) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + uint8_t hash_alg_id = cbor_get_uint8(cbor_hash_alg_id); + switch (hash_alg_id) { + /* assume that RESERVED (ID = 0) means SHA256 */ + case IANA_NAMED_INFO_HASH_ALG_REGISTRY_RESERVED: + case IANA_NAMED_INFO_HASH_ALG_REGISTRY_SHA256: { + if (cbor_bytestring_length(cbor_hash_value) != SHA256_DIGEST_SIZE) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + uint8_t sha[SHA256_DIGEST_SIZE]; + ret = mbedtls_sha256(pk_der, pk_der_size, sha, /*is224=*/0); + if (ret < 0) + goto out; + + ret = memcmp(cbor_bytestring_handle(cbor_hash_value), sha, sizeof(sha)); + if (ret) { + ret = MBEDTLS_ERR_X509_SIG_MISMATCH; + goto out; + } + + break; + } + + /* TODO: add other recognized hash functions on a need basis */ + + default: + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + ret = 0; +out: + if (cbor_hash_alg_id) + cbor_decref(&cbor_hash_alg_id); + if (cbor_hash_value) + cbor_decref(&cbor_hash_value); + return ret; +} + +static int extract_standard_quote_and_verify_claims(mbedtls_x509_crt* crt, sgx_quote_t** out_quote, + size_t* out_quote_size) { + /* for description of evidence format, see ra_tls_attest.c:generate_evidence_with_claims() */ + cbor_item_t* cbor_tagged_evidence = NULL; + cbor_item_t* cbor_evidence = NULL; + cbor_item_t* cbor_quote = NULL; + cbor_item_t* cbor_claims = NULL; /* serialized CBOR map of claims (as bytestring) */ + cbor_item_t* cbor_claims_map = NULL; + cbor_item_t* cbor_hash_entry = NULL; + sgx_quote_t* quote = NULL; + + uint8_t* evidence_buf; + size_t evidence_buf_size; + int ret = find_oid(crt->v3_ext.p, crt->v3_ext.len, g_evidence_oid_raw, g_evidence_oid_raw_size, + &evidence_buf, &evidence_buf_size); + if (ret < 0) + return ret; + + struct cbor_load_result cbor_result; + cbor_tagged_evidence = cbor_load(evidence_buf, evidence_buf_size, &cbor_result); + if (cbor_result.error.code != CBOR_ERR_NONE) { + ERROR("Certificate: cannot parse 'tagged evidence' OID in CBOR format (error %d)\n", + cbor_result.error.code); + ret = (cbor_result.error.code == CBOR_ERR_MEMERROR) ? MBEDTLS_ERR_X509_ALLOC_FAILED + : MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + if (!cbor_isa_tag(cbor_tagged_evidence) + || cbor_tag_value(cbor_tagged_evidence) != TCG_DICE_TAGGED_EVIDENCE_CBOR_TAG) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + cbor_evidence = cbor_tag_item(cbor_tagged_evidence); + if (!cbor_evidence || !cbor_isa_array(cbor_evidence) + || !cbor_array_is_definite(cbor_evidence)) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + if (cbor_array_size(cbor_evidence) != 2) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + cbor_quote = cbor_array_get(cbor_evidence, /*index=*/0); + if (!cbor_quote || !cbor_isa_bytestring(cbor_quote) || !cbor_bytestring_is_definite(cbor_quote) + || cbor_bytestring_length(cbor_quote) == 0) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + size_t quote_size = cbor_bytestring_length(cbor_quote); + if (quote_size < sizeof(*quote)) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + quote = malloc(quote_size); + if (!quote) { + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + goto out; + } + memcpy(quote, cbor_bytestring_handle(cbor_quote), quote_size); + + cbor_claims = cbor_array_get(cbor_evidence, /*index=*/1); + if (!cbor_claims || !cbor_isa_bytestring(cbor_claims) + || !cbor_bytestring_is_definite(cbor_claims) + || cbor_bytestring_length(cbor_claims) == 0) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + /* claims object is borrowed, no need to free separately */ + uint8_t* claims_buf = cbor_bytestring_handle(cbor_claims); + size_t claims_buf_size = cbor_bytestring_length(cbor_claims); + assert(claims_buf && claims_buf_size); + + /* verify that SGX quote corresponds to the attached serialized claims */ + uint8_t sha[SHA256_DIGEST_SIZE]; + ret = mbedtls_sha256(claims_buf, claims_buf_size, sha, /*is224=*/0); + if (ret < 0) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + ret = memcmp(quote->body.report_body.report_data.d, sha, SHA256_DIGEST_SIZE); + if (ret) { + ret = MBEDTLS_ERR_X509_SIG_MISMATCH; + goto out; + } + + /* parse and verify CBOR claims */ + cbor_claims_map = cbor_load(claims_buf, claims_buf_size, &cbor_result); + if (cbor_result.error.code != CBOR_ERR_NONE) { + ERROR("Certificate: cannot parse serialized CBOR map of claims (error %d)\n", + cbor_result.error.code); + ret = (cbor_result.error.code == CBOR_ERR_MEMERROR) ? MBEDTLS_ERR_X509_ALLOC_FAILED + : MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + if (!cbor_isa_map(cbor_claims_map) || !cbor_map_is_definite(cbor_claims_map) + || cbor_map_size(cbor_claims_map) < 1) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + struct cbor_pair* claims_pairs = cbor_map_handle(cbor_claims_map); + for (size_t i = 0; i < cbor_map_size(cbor_claims_map); i++) { + if (!claims_pairs[i].key || !cbor_isa_string(claims_pairs[i].key) + || !cbor_string_is_definite(claims_pairs[i].key) + || cbor_string_length(claims_pairs[i].key) == 0) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + if (strncmp((char*)cbor_string_handle(claims_pairs[i].key), "pubkey-hash", + cbor_string_length(claims_pairs[i].key)) == 0) { + /* claim { "pubkey-hash" : serialized CBOR array hash-entry (as CBOR bstr) } */ + if (!claims_pairs[i].value || !cbor_isa_bytestring(claims_pairs[i].value) + || !cbor_bytestring_is_definite(claims_pairs[i].value) + || cbor_bytestring_length(claims_pairs[i].value) == 0) { + ret = MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + uint8_t* hash_entry_buf = cbor_bytestring_handle(claims_pairs[i].value); + size_t hash_entry_buf_size = cbor_bytestring_length(claims_pairs[i].value); + + cbor_hash_entry = cbor_load(hash_entry_buf, hash_entry_buf_size, &cbor_result); + if (cbor_result.error.code != CBOR_ERR_NONE) { + ERROR("Certificate: cannot parse 'pubkey-hash' array in CBOR format (error %d)\n", + cbor_result.error.code); + ret = (cbor_result.error.code == CBOR_ERR_MEMERROR) ? MBEDTLS_ERR_X509_ALLOC_FAILED + : MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + goto out; + } + + ret = cmp_crt_pk_against_cbor_claim_hash_entry(crt, cbor_hash_entry); + if (ret < 0) + goto out; + } else { + INFO("WARNING: Unrecognized claim in TCG DICE 'tagged evidence' OID, ignoring.\n"); + } + } + + *out_quote = quote; + *out_quote_size = quote_size; + ret = 0; +out: + if (ret < 0) + free(quote); + if (cbor_hash_entry) + cbor_decref(&cbor_hash_entry); + if (cbor_claims_map) + cbor_decref(&cbor_claims_map); + if (cbor_claims) + cbor_decref(&cbor_claims); + if (cbor_quote) + cbor_decref(&cbor_quote); + if (cbor_evidence) + cbor_decref(&cbor_evidence); + if (cbor_tagged_evidence) + cbor_decref(&cbor_tagged_evidence); + return ret; +} + +static int extract_legacy_quote_and_verify_pubkey(mbedtls_x509_crt* crt, sgx_quote_t** out_quote, + size_t* out_quote_size) { sgx_quote_t* quote; size_t quote_size; + int ret = find_oid(crt->v3_ext.p, crt->v3_ext.len, g_quote_oid, g_quote_oid_size, (uint8_t**)"e, "e_size); if (ret < 0) @@ -223,11 +466,29 @@ int extract_quote_and_verify_pubkey(mbedtls_x509_crt* crt, sgx_quote_t** out_quo if (ret < 0) return ret; - *out_quote = quote; + /* quote returned by find_oid() is a pointer somewhere inside of the X.509 cert object; let's + * copy it into a newly allocated object to correctly track ownership */ + sgx_quote_t* allocated_quote = malloc(quote_size); + if (!allocated_quote) + return MBEDTLS_ERR_X509_ALLOC_FAILED; + memcpy(allocated_quote, quote, quote_size); + + *out_quote = allocated_quote; *out_quote_size = quote_size; return 0; } +int extract_quote_and_verify_claims(mbedtls_x509_crt* crt, sgx_quote_t** out_quote, + size_t* out_quote_size) { + int ret = extract_standard_quote_and_verify_claims(crt, out_quote, out_quote_size); + if (!ret) + return 0; + + INFO("WARNING: TCG DICE 'tagged evidence' OID was not found. Checking non-standard legacy " + "Gramine OID. This will be deprecated in the future.\n"); + return extract_legacy_quote_and_verify_pubkey(crt, out_quote, out_quote_size); +} + void ra_tls_set_measurement_callback(int (*f_cb)(const char* mrenclave, const char* mrsigner, const char* isv_prod_id, const char* isv_svn)) { g_verify_measurements_cb = f_cb; diff --git a/tools/sgx/ra-tls/ra_tls_verify_dcap.c b/tools/sgx/ra-tls/ra_tls_verify_dcap.c index 572b47c9de..85fd6e883e 100644 --- a/tools/sgx/ra-tls/ra_tls_verify_dcap.c +++ b/tools/sgx/ra-tls/ra_tls_verify_dcap.c @@ -99,6 +99,7 @@ int ra_tls_verify_callback(void* data, mbedtls_x509_crt* crt, int depth, uint32_ (void)data; int ret; + sgx_quote_t* quote = NULL; uint8_t* supplemental_data = NULL; uint32_t supplemental_data_size = 0; @@ -116,9 +117,8 @@ int ra_tls_verify_callback(void* data, mbedtls_x509_crt* crt, int depth, uint32_ } /* extract SGX quote from "quote" OID extension from crt */ - sgx_quote_t* quote; size_t quote_size; - ret = extract_quote_and_verify_pubkey(crt, "e, "e_size); + ret = extract_quote_and_verify_claims(crt, "e, "e_size); if (ret < 0) goto out; @@ -212,6 +212,7 @@ int ra_tls_verify_callback(void* data, mbedtls_x509_crt* crt, int depth, uint32_ ret = 0; out: + free(quote); free(supplemental_data); return ret; } diff --git a/tools/sgx/ra-tls/ra_tls_verify_epid.c b/tools/sgx/ra-tls/ra_tls_verify_epid.c index e3491b28c0..2f30fc8386 100644 --- a/tools/sgx/ra-tls/ra_tls_verify_epid.c +++ b/tools/sgx/ra-tls/ra_tls_verify_epid.c @@ -121,6 +121,8 @@ int ra_tls_verify_callback(void* data, mbedtls_x509_crt* crt, int depth, uint32_ (void)data; int ret; + sgx_quote_t* quote = NULL; + struct ias_context_t* ias = NULL; char* ias_pub_key_pem = NULL; @@ -160,9 +162,8 @@ int ra_tls_verify_callback(void* data, mbedtls_x509_crt* crt, int depth, uint32_ goto out; /* extract SGX quote from "quote" OID extension from crt */ - sgx_quote_t* quote; size_t quote_size; - ret = extract_quote_and_verify_pubkey(crt, "e, "e_size); + ret = extract_quote_and_verify_claims(crt, "e, "e_size); if (ret < 0) goto out; @@ -256,6 +257,7 @@ int ra_tls_verify_callback(void* data, mbedtls_x509_crt* crt, int depth, uint32_ if (ias) ias_cleanup(ias); + free(quote); free(ias_pub_key_pem); free(quote_from_ias); free(report_data);