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:
parent
4e02db367e
commit
e8e14350a5
@ -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": ""
|
||||
}
|
5
demos/remote_attestation/conf/ra_config.json
Normal file
5
demos/remote_attestation/conf/ra_config.json
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user