Support access key in remote attestaion demo

1. add access key configuration and code
2. Upgrade libcurl to support https
3. Support debug compile mode

Signed-off-by: Junxian Xiao <junxian.xjx@antfin.com>
This commit is contained in:
Junxian Xiao 2020-05-26 16:30:07 +08:00 committed by tate.thl
parent 4e02db367e
commit e8e14350a5
14 changed files with 80 additions and 40 deletions

@ -8,6 +8,10 @@ MESSAGE(STATUS "SOURCE dir " ${CMAKE_CURRENT_SOURCE_DIR})
SET(SGXSDK_INSTALL_DIR /opt/intel/sgxsdk)
SET(OCCLUM_INSTALL_DIR /usr/local/occlum/x86_64-linux-musl)
if(BUILD_MODE STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g2 -DDEBUG -UNDEBUG -UEDEBUG")
endif()
FILE(GLOB LIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/lib/src/*.cpp)
SET(RALIB occlumra)

@ -2,17 +2,35 @@
This project demonstrates how to do remote attestation on Occlum.
In a nutshell, Occlum provides SGX capabilities to user apps through ioctls on a special device (`/dev/sgx`). To hide the low-level details of ioctls from user apps, a user-friendly, remote attestation library is provided in this demo.
In a nutshell, Occlum provides SGX capabilities to user apps through ioctls on a special device (`/dev/sgx`).
To hide the low-level details of ioctls from user apps, a user-friendly, remote attestation library is provided in this demo.
**Prerequisites.** This demo needs to access Intel Attestation Service (IAS). To do this, a developer needs to contact Intel to obtain a Service Provider ID (SPID) and the associated Service Provider certificate. The certificate and key files should be put into `conf/certs`, and configure the SPID and paths of the certificate and key files in `conf/ra_config.example.json`.
**Prerequisites.** This demo needs to access Intel Attestation Service (IAS). To do this,
a developer needs to contact Intel to obtain a Service Provider ID (SPID) and the associated
Access Key from [here](https://api.portal.trustedservices.intel.com/EPID-attestation).
After obtaining the SPID and Access Key, fill them in the config file `conf/ra_config.json` as shown below:
```
{
"ias_url": "https://api.trustedservices.intel.com/sgx/dev/attestation/v4",
"ias_access_key": "<YourAccessKey>",
"enclave_spid": "<YourSPID>"
}
```
**NOTE:** The URL, SPID and Access Key above vary depending whether it is for development or production
**Step 1.** Build this demo
Build the code in debug mode with "--debug", otherwise it's in Relese mode by default.
```
download_and_build.sh
./download_and_build.sh [--debug]
```
**Step 2.** Run this demo on Occlum
Build the occlum image and run the RA test application.
```
run_on_occlum.sh
./run_on_occlum.sh
```

@ -17,6 +17,7 @@ constexpr char kRaConf[] = "ra_config.json";
constexpr char kConfIasServer[] = "ias_url";
constexpr char kConfIasCert[] = "ias_sp_cert_file";
constexpr char kConfIasKey[] = "ias_sp_key_file";
constexpr char kConfIasAccessKey[] = "ias_access_key";
constexpr char kConfSPID[] = "enclave_spid";
#define RA_CONF_STR(name) SofaeConfGetStr(kRaConf, name)

@ -37,6 +37,7 @@ int main() {
std::string endpoint = RA_CONF_STR(kConfIasServer);
std::string cert = RA_CONF_STR(kConfIasCert);
std::string key = RA_CONF_STR(kConfIasKey);
std::string access_key = RA_CONF_STR(kConfIasAccessKey);
std::string spid_str = RA_CONF_STR(kConfSPID);
if (spid_str.empty()) {
@ -44,7 +45,7 @@ int main() {
return -1;
}
SofaeServerCfg ias_server = {endpoint, cert, key};
SofaeServerCfg ias_server = {endpoint, cert, key, access_key};
SofaeEnclaveQuote quote = {0};
SofaeQuoteArgs quote_args = {0};
quote_args.quote_type = SGX_LINKABLE_SIGNATURE;

@ -1,6 +0,0 @@
{
"ias_url": "",
"ias_sp_cert_file": "/etc/certs/sp_client.crt",
"ias_sp_key_file": "/etc/certs/sp_client.key",
"enclave_spid": ""
}

@ -0,0 +1,5 @@
{
"ias_url": "https://api.trustedservices.intel.com/sgx/dev/attestation/v4",
"ias_access_key": "",
"enclave_spid": ""
}

@ -7,6 +7,9 @@ THISDIR="$(dirname $(readlink -f $0))"
INSTALLDIR="/usr/local/occlum/x86_64-linux-musl"
DEPSDIR="$THISDIR/deps"
BUILDMODE="Release"
[ "$1" == "--debug" ] && BUILDMODE="Debug"
mkdir -p $DEPSDIR || exit 1
# Download OpenSSL 1.1.1
@ -27,9 +30,9 @@ CURLDIR="${DEPSDIR}/curl"
if [ ! -d "$CURLDIR" ] ; then
echo "Downloading curl ..."
cd "$DEPSDIR" && \
wget https://github.com/curl/curl/archive/curl-7_29_0.tar.gz && \
tar -xvf curl-7_29_0.tar.gz && \
mv curl-curl-7_29_0 curl && \
wget https://github.com/curl/curl/archive/curl-7_70_0.tar.gz && \
tar -xvf curl-7_70_0.tar.gz && \
mv curl-curl-7_70_0 curl && \
echo "Download curl successfully" || exit 1
else
echo "The curl code is already existent"
@ -101,5 +104,5 @@ fi
echo "Build demo source code"
cd "$THISDIR" && rm -rf ./build && mkdir -p build
cd build && \
cmake -DCMAKE_CXX_COMPILER=occlum-g++ ../ && \
cmake -DCMAKE_CXX_COMPILER=occlum-g++ -DBUILD_MODE=${BUILDMODE} ../ && \
make -j$(nproc)

@ -53,6 +53,7 @@ typedef struct {
std::string endpoint;
std::string cert;
std::string key;
std::string accesskey;
} SofaeServerCfg;
#endif // REMOTE_ATTESTATION_LIB_INCLUDE_SOFAENCLAVE_COMMON_TYPE_H_

@ -4,7 +4,7 @@
#include <mutex>
#include <string>
#include "./sgx_uae_service.h"
#include "./sgx_uae_epid.h"
#include "./sgx_urts.h"
#include "./sgx_utils.h"
@ -27,7 +27,7 @@ class RaIasClient {
~RaIasClient();
SofaeErrorCode GetSigRL(const sgx_epid_group_id_t* gid, std::string* sigrl);
SofaeErrorCode GetSigRL(const sgx_epid_group_id_t& gid, std::string* sigrl);
SofaeErrorCode FetchReport(const std::string& quote, IasReport* ias_report);
private:

@ -49,7 +49,7 @@ SofaeErrorCode GetQuote(SofaeQuoteArgs* quote_args);
* @retval Others when failed
*/
SofaeErrorCode FetchIasSigRL(const SofaeServerCfg& ias_server,
sgx_epid_group_id_t* gid,
const sgx_epid_group_id_t& gid,
std::string* sigrl);
/**

@ -20,8 +20,10 @@ constexpr char kStrQuoteStatus[] = "isvEnclaveQuoteStatus";
constexpr char kStrPlatform[] = "platformInfoBlob";
constexpr char kStrQuoteBody[] = "isvEnclaveQuoteBody";
constexpr char kStrHeaderSig[] = "x-iasreport-signature:";
constexpr char kStrHeaderCA[] = "x-iasreport-signing-certificate:";
constexpr char kStrHeaderAdvisoryURL[] = "advisory-url:";
constexpr char kStrHeaderSigAk[] = "X-IASReport-Signature:";
constexpr char kStrHeaderCa[] = "x-iasreport-signing-certificate:";
constexpr char kStrHeaderCaAk[] = "X-IASReport-Signing-Certificate:";
constexpr char kStrHeaderAdvisoryUrl[] = "advisory-url:";
constexpr char kStrHeaderAdvisoryIDs[] = "advisory-ids:";
typedef struct {
@ -95,11 +97,15 @@ static size_t ParseReportResponseHeader(const void* contents, size_t size,
if (strncmp(header, kStrHeaderSig, strlen(kStrHeaderSig)) == 0) {
report->set_b64_signature(GetHeaderValue(header, kStrHeaderSig));
} else if (strncmp(header, kStrHeaderCA, strlen(kStrHeaderCA)) == 0) {
report->set_signing_cert(GetHeaderValue(header, kStrHeaderCA));
} else if (strncmp(header, kStrHeaderAdvisoryURL,
strlen(kStrHeaderAdvisoryURL)) == 0) {
report->set_advisory_url(GetHeaderValue(header, kStrHeaderAdvisoryURL));
} else if (strncmp(header, kStrHeaderSigAk, strlen(kStrHeaderSigAk)) == 0) {
report->set_b64_signature(GetHeaderValue(header, kStrHeaderSigAk));
} else if (strncmp(header, kStrHeaderCa, strlen(kStrHeaderCa)) == 0) {
report->set_signing_cert(GetHeaderValue(header, kStrHeaderCa));
} else if (strncmp(header, kStrHeaderCaAk, strlen(kStrHeaderCaAk)) == 0) {
report->set_signing_cert(GetHeaderValue(header, kStrHeaderCaAk));
} else if (strncmp(header, kStrHeaderAdvisoryUrl,
strlen(kStrHeaderAdvisoryUrl)) == 0) {
report->set_advisory_url(GetHeaderValue(header, kStrHeaderAdvisoryUrl));
} else if (strncmp(header, kStrHeaderAdvisoryIDs,
strlen(kStrHeaderAdvisoryIDs)) == 0) {
report->set_advisory_ids(GetHeaderValue(header, kStrHeaderAdvisoryIDs));
@ -144,6 +150,8 @@ void RaIasClient::InitIasConnection(const std::string& endpoint) {
curl_easy_setopt(curl_, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(curl_, CURLOPT_TIMEOUT, 60L);
curl_easy_setopt(curl_, CURLOPT_CONNECTTIMEOUT, 10L);
curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYHOST, 0L);
server_endpoint_ = endpoint;
}
@ -157,13 +165,19 @@ RaIasClient::RaIasClient(const SofaeServerCfg& ias_server) {
InitIasConnection(ias_server.endpoint);
// Check the HTTPS server addr and set the cert/key settings
if (curl_ && (ias_server.endpoint.find("https://") != std::string::npos)) {
// Or use the Access key authentication
std::string header_access_key = "Ocp-Apim-Subscription-Key: ";
if (!ias_server.accesskey.empty()) {
header_access_key += ias_server.accesskey;
headers_ = curl_slist_append(headers_, header_access_key.c_str());
}
if (curl_ && (ias_server.endpoint.find("https://") != std::string::npos) && \
(ias_server.accesskey.empty())) {
const char *ias_cert_key_type = "PEM";
SOFAE_LOG_DEBUG("IAS cert: %s", ias_server.cert.c_str());
SOFAE_LOG_DEBUG("IAS key: %s", ias_server.key.c_str());
curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl_, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl_, CURLOPT_SSLCERT, ias_server.cert.c_str());
curl_easy_setopt(curl_, CURLOPT_SSLKEY, ias_server.key.c_str());
curl_easy_setopt(curl_, CURLOPT_SSLCERTTYPE, ias_cert_key_type);
@ -186,7 +200,7 @@ RaIasClient::~RaIasClient() {
}
}
SofaeErrorCode RaIasClient::GetSigRL(const sgx_epid_group_id_t *gid,
SofaeErrorCode RaIasClient::GetSigRL(const sgx_epid_group_id_t& gid,
std::string *sigrl) {
if (!curl_) {
SOFAE_LOG_ERROR("IAS client is not initialized");
@ -194,8 +208,8 @@ SofaeErrorCode RaIasClient::GetSigRL(const sgx_epid_group_id_t *gid,
}
/* Set the URL */
std::string url = server_endpoint_ + "/attestation/sgx/v3/sigrl/";
std::vector<char> tmp_gid_vec(sizeof(sgx_epid_group_id_t) * 2, 0);
std::string url = server_endpoint_ + "/sigrl/";
std::vector<char> tmp_gid_vec(sizeof(sgx_epid_group_id_t) * 2 + 1, 0);
snprintf(tmp_gid_vec.data(), tmp_gid_vec.size(), "%02X%02X%02X%02X", gid[3],
gid[2], gid[1], gid[0]);
url += std::string(tmp_gid_vec.data());
@ -242,7 +256,7 @@ SofaeErrorCode RaIasClient::FetchReport(const std::string& quote,
}
/* Set the report url */
std::string url = server_endpoint_ + "/attestation/sgx/v3/report";
std::string url = server_endpoint_ + "/report";
SOFAE_LOG_DEBUG("URL: %s", url.c_str());
curl_easy_setopt(curl_, CURLOPT_URL, url.c_str());

@ -46,7 +46,7 @@ JsonConfig* JsonConfig::GetInstance() {
template <typename T>
bool JsonConfig::CheckString(const T& conf, const char* name) {
if (!conf.HasMember(name) || !conf[name].IsString()) {
SOFAE_LOG_ERROR("%s is missed or not string in config file", name);
SOFAE_LOG_DEBUG("%s is missed or not string in config file", name);
return false;
}
return true;
@ -55,7 +55,7 @@ bool JsonConfig::CheckString(const T& conf, const char* name) {
template <typename T>
bool JsonConfig::CheckArray(const T& conf, const char* name) {
if (!conf.HasMember(name) || !conf[name].IsArray()) {
SOFAE_LOG_ERROR("%s is missed or not array in config file", name);
SOFAE_LOG_DEBUG("%s is missed or not array in config file", name);
return false;
}
return true;
@ -64,7 +64,7 @@ bool JsonConfig::CheckArray(const T& conf, const char* name) {
template <typename T>
bool JsonConfig::CheckInt(const T& conf, const char* name) {
if (!conf.HasMember(name) || !conf[name].IsInt()) {
SOFAE_LOG_ERROR("%s is missed or not integer in config file", name);
SOFAE_LOG_DEBUG("%s is missed or not integer in config file", name);
return false;
}
return true;
@ -73,7 +73,7 @@ bool JsonConfig::CheckInt(const T& conf, const char* name) {
template <typename T>
bool JsonConfig::CheckObj(const T& conf, const char* name) {
if (!conf.HasMember(name) || !conf[name].IsObject()) {
SOFAE_LOG_ERROR("%s is missed or not object in config file", name);
SOFAE_LOG_DEBUG("%s is missed or not object in config file", name);
return false;
}
return true;

@ -35,7 +35,7 @@ SofaeErrorCode GetQuote(SofaeQuoteArgs* quote_args) {
}
SofaeErrorCode FetchIasSigRL(const SofaeServerCfg& ias_server,
sgx_epid_group_id_t* gid,
const sgx_epid_group_id_t& gid,
std::string* sigrl) {
sofaenclave::occlum::RaIasClient ias_client(ias_server);
return ias_client.GetSigRL(gid, sigrl);
@ -63,7 +63,7 @@ SofaeErrorCode GetQuoteAndFetchIasReport(const SofaeServerCfg& ias_server,
// If there is no SigRL, try to fetch it.
if (!quote_args->sigrl_ptr || (quote_args->sigrl_len == 0)) {
std::string sigrl_str;
ret = FetchIasSigRL(ias_server, &gid, &sigrl_str);
ret = FetchIasSigRL(ias_server, gid, &sigrl_str);
if (ret != SOFAE_SUCCESS) {
return ret;
}

@ -14,8 +14,7 @@ mkdir -p image/etc
mkdir -p image/etc/certs
cp /etc/resolv.conf image/etc
cp /etc/hosts image/etc
cp $THISDIR/conf/ra_config.example.json image/etc/ra_config.json
cp $THISDIR/conf/certs/* image/etc/certs
cp $THISDIR/conf/ra_config.json image/etc/
cp $THISDIR/build/$DEMPOAPP image/bin
cp /usr/local/occlum/x86_64-linux-musl/lib/libssl.so.1.1 image/lib
cp /usr/local/occlum/x86_64-linux-musl/lib/libcrypto.so.1.1 image/lib