Skip to content

Commit

Permalink
Updating collateral verification API to fetch custom data. (#157)
Browse files Browse the repository at this point in the history
* Updating collateral verification API to fetch custom data.

* Updating TCB info API request.

* converting custom param to base64 before appending to the URL.

* Updating base64 conversion algo.

* updating function signature for  sgx_ql_get_quote_verification_collateral_with_params.

* Handling rebasing conflicts.

* Passing JSON without flattening to extract_from_json() method.

* Updating curl command threshold to run cache tests.

* Adding test case for icelake cluster to fetch custom params.

* Catch exceptions as reference to handle polymorphic type error.

* reverting the API version to call into THIM service.
  • Loading branch information
msft-gumunjal authored Jun 14, 2022
1 parent ddb9b28 commit 723a6f3
Show file tree
Hide file tree
Showing 6 changed files with 621 additions and 65 deletions.
246 changes: 242 additions & 4 deletions src/UnitTest/test_quote_prov.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ typedef quote3_error_t (*sgx_ql_get_quote_verification_collateral_t)(
const char* pck_ca,
sgx_ql_qve_collateral_t** pp_quote_collateral);

typedef quote3_error_t (*sgx_ql_get_quote_verification_collateral_with_params_t)(
const uint8_t* fmspc,
const uint16_t fmspc_size,
const char* pck_ca,
const void* custom_param,
const uint16_t custom_param_length,
sgx_ql_qve_collateral_t** pp_quote_collateral);

typedef quote3_error_t (*sgx_ql_get_qve_identity_t)(
char** pp_qve_identity,
uint32_t* p_qve_identity_size,
Expand All @@ -93,13 +101,19 @@ static sgx_ql_free_qve_identity_t sgx_ql_free_qve_identity;
static sgx_ql_free_root_ca_crl_t sgx_ql_free_root_ca_crl;
static sgx_ql_get_quote_verification_collateral_t
sgx_ql_get_quote_verification_collateral;
static sgx_ql_get_quote_verification_collateral_with_params_t
sgx_ql_get_quote_verification_collateral_with_params;
static sgx_ql_get_qve_identity_t sgx_ql_get_qve_identity;
static sgx_ql_get_root_ca_crl_t sgx_ql_get_root_ca_crl;

// Test FMSPC
static constexpr uint8_t TEST_FMSPC[] = {0x00, 0x90, 0x6E, 0xA1, 0x00, 0x00};
static constexpr uint8_t ICX_TEST_FMSPC[] = {0x00, 0x60, 0x6a, 0x00, 0x00, 0x00};

const uint16_t custom_param_length = 45;
const char *custom_param = "tcbEvaluationDataNumber=11;region=us central";
std::string tcbEvaluationDataNumber = "11";

// Test input (choose an arbitrary Azure server)
static uint8_t qe_id[16] = {
0x00,
Expand Down Expand Up @@ -205,6 +219,8 @@ static void Log(sgx_ql_log_level_t level, const char* message)
printf("[%s]: %s\n", levelText, message);
}



#if defined __LINUX__
static void* LoadFunctions()
{
Expand Down Expand Up @@ -253,6 +269,11 @@ static void* LoadFunctions()
dlsym(library, "sgx_ql_free_root_ca_crl"));
EXPECT_NE(sgx_ql_free_root_ca_crl, nullptr);

sgx_ql_get_quote_verification_collateral_with_params = reinterpret_cast<
sgx_ql_get_quote_verification_collateral_with_params_t>(
dlsym(library, "sgx_ql_get_quote_verification_collateral_with_params"));
EXPECT_NE(sgx_ql_get_quote_verification_collateral_with_params, nullptr);

sgx_ql_get_quote_verification_collateral =
reinterpret_cast<sgx_ql_get_quote_verification_collateral_t>(
dlsym(library, "sgx_ql_get_quote_verification_collateral"));
Expand Down Expand Up @@ -321,6 +342,11 @@ static HINSTANCE LoadFunctions()
hLibCapdll, "sgx_ql_get_quote_verification_collateral"));
EXPECT_NE(sgx_ql_get_quote_verification_collateral, nullptr);

sgx_ql_get_quote_verification_collateral_with_params = reinterpret_cast<
sgx_ql_get_quote_verification_collateral_with_params_t>(GetProcAddress(
hLibCapdll, "sgx_ql_get_quote_verification_collateral_with_params"));
EXPECT_NE(sgx_ql_get_quote_verification_collateral_with_params, nullptr);

sgx_ql_get_qve_identity = reinterpret_cast<sgx_ql_get_qve_identity_t>(
GetProcAddress(hLibCapdll, "sgx_ql_get_qve_identity"));
EXPECT_NE(sgx_ql_get_qve_identity, nullptr);
Expand All @@ -333,6 +359,33 @@ static HINSTANCE LoadFunctions()
}
#endif

//
// extract raw value from response body, if exists
//
sgx_plat_error_t extract_from_json(
const nlohmann::json& json,
const std::string& item,
std::string* out_header)
{
try
{
nlohmann::json raw_value = json[item];
if (!raw_value.is_string())
{
raw_value = raw_value.dump();
}
if (out_header != nullptr)
{
*out_header = raw_value;
}
}
catch (const exception& ex)
{
return SGX_PLAT_ERROR_UNEXPECTED_SERVER_RESPONSE;
}
return SGX_PLAT_ERROR_OK;
}

//
// Fetches and validates certification data for a platform
//
Expand Down Expand Up @@ -511,6 +564,40 @@ static void GetVerificationCollateralTest()
VerifyCollateral(collateral);
}

//
// Fetches and validates verification APIs of QPL with custom params provided
//
static void GetVerificationCollateralTestWithParams()
{
// Test input (choose an arbitrary Azure server)

sgx_ql_qve_collateral_t* collateral = nullptr;
std::string tcbInfoTcbEvaluationDataNumber;
std::string enclaveIdentityTcbEvaluationDataNumber;
nlohmann::json json_body;
quote3_error_t result = sgx_ql_get_quote_verification_collateral_with_params(
TEST_FMSPC,
sizeof(TEST_FMSPC),
"processor",
custom_param,
custom_param_length,
&collateral);
ASSERT_TRUE(SGX_QL_SUCCESS == result);
json_body = nlohmann::json::parse(collateral->tcb_info);
extract_from_json(
json_body.flatten(),
"/tcbInfo/tcbEvaluationDataNumber",
&tcbInfoTcbEvaluationDataNumber);
ASSERT_TRUE(tcbInfoTcbEvaluationDataNumber.compare(tcbEvaluationDataNumber) == 0);
json_body = nlohmann::json::parse(collateral->qe_identity);
extract_from_json(
json_body.flatten(),
"/enclaveIdentity/tcbEvaluationDataNumber",
&enclaveIdentityTcbEvaluationDataNumber);
ASSERT_TRUE(enclaveIdentityTcbEvaluationDataNumber.compare(tcbEvaluationDataNumber) == 0);
VerifyCollateral(collateral);
}

//
// Fetches and validates verification APIs of QPL
//
Expand All @@ -526,6 +613,38 @@ static void GetVerificationCollateralTestICXV3()
VerifyCollateral(collateral);
}

//
// Fetches and validates verification APIs of QPL with custom params provided
//
static void GetVerificationCollateralTestICXV3WithParams()
{
sgx_ql_qve_collateral_t* collateral = nullptr;
std::string tcbEvaluationDataNumber;
std::string enclaveIdentityTcbEvaluationDataNumber;
quote3_error_t result = sgx_ql_get_quote_verification_collateral_with_params(
ICX_TEST_FMSPC,
sizeof(ICX_TEST_FMSPC),
"platform",
custom_param,
custom_param_length,
&collateral);
ASSERT_TRUE(SGX_QL_SUCCESS == result);
nlohmann::json json_body = nlohmann::json::parse(collateral->tcb_info);
extract_from_json(
json_body.flatten(),
"/tcbInfo/tcbEvaluationDataNumber",
&tcbEvaluationDataNumber);
ASSERT_TRUE(tcbEvaluationDataNumber.compare(tcbEvaluationDataNumber) == 0);
json_body = nlohmann::json::parse(collateral->qe_identity);
extract_from_json(
json_body.flatten(),
"/enclaveIdentity/tcbEvaluationDataNumber",
&enclaveIdentityTcbEvaluationDataNumber);
ASSERT_TRUE(
enclaveIdentityTcbEvaluationDataNumber.compare(tcbEvaluationDataNumber) == 0);
VerifyCollateral(collateral);
}

static boolean GetQveIdentityTest()
{
boolean TEST_SUCCESS = false;
Expand Down Expand Up @@ -569,7 +688,7 @@ static void GetRootCACrlTest()
#ifdef __LINUX__
constexpr auto CURL_TOLERANCE = 0.002;
#else
constexpr auto CURL_TOLERANCE = 0.004;
constexpr auto CURL_TOLERANCE = 0.008;
#endif

static inline float MeasureFunction(measured_function_t func)
Expand Down Expand Up @@ -603,7 +722,6 @@ static inline void VerifyDurationChecks(
EXPECT_TRUE(
fabs(duration_curl_verification - duration_local_verification) >
CURL_TOLERANCE);

constexpr int NUMBER_VERIFICATION_CURL_CALLS = 4;
EXPECT_TRUE(
duration_local_verification <
Expand Down Expand Up @@ -636,6 +754,33 @@ boolean RunQuoteProviderTests(bool caching_enabled = false)
return true;
}

boolean RunQuoteProviderTestsWithCustomParams(bool caching_enabled = false)
{
local_cache_clear();
auto duration_curl_cert = MeasureFunction(GetCertsTest);
GetCrlTest();
auto duration_curl_verification_with_params =
MeasureFunction(GetVerificationCollateralTestWithParams);
GetRootCACrlTest();

//
// Second pass: Ensure that we ONLY get data from the cache
//
auto duration_local_cert = MeasureFunction(GetCertsTest);
GetCrlTest();
GetRootCACrlTest();
auto duration_local_verification_with_params =
MeasureFunction(GetVerificationCollateralTestWithParams);
VerifyDurationChecks(
duration_local_cert,
duration_local_verification_with_params,
duration_curl_cert,
duration_curl_verification_with_params,
caching_enabled);

return true;
}

boolean RunQuoteProviderTestsICXV3(bool caching_enabled = false)
{
local_cache_clear();
Expand All @@ -660,6 +805,32 @@ boolean RunQuoteProviderTestsICXV3(bool caching_enabled = false)
return true;
}

boolean RunQuoteProviderTestsICXV3WithParam(bool caching_enabled = false)
{
local_cache_clear();
auto duration_curl_cert = MeasureFunction(GetCertsTestICXV3);
GetCrlTestICXV3();
auto duration_curl_verification_with_params =
MeasureFunction(GetVerificationCollateralTestICXV3WithParams);
GetRootCACrlTest();

//
// Second pass: Ensure that we ONLY get data from the cache
//
auto duration_local_cert = MeasureFunction(GetCertsTestICXV3);
GetCrlTestICXV3();
GetRootCACrlTest();
auto duration_local_verification_with_params =
MeasureFunction(GetVerificationCollateralTestICXV3WithParams);
VerifyDurationChecks(
duration_local_cert,
duration_local_verification_with_params,
duration_curl_cert,
duration_curl_verification_with_params,
caching_enabled);
return true;
}

void ReloadLibrary(libary_type_t* library, bool set_logging_callback = true)
{
#if defined __LINUX__
Expand Down Expand Up @@ -829,7 +1000,8 @@ boolean RunCachePermissionTests(libary_type_t* library)
{STANDARD_RIGHTS_ALL, SET_ACCESS},
{GENERIC_READ | GENERIC_WRITE, DENY_ACCESS},
{GENERIC_READ, DENY_ACCESS},
{GENERIC_WRITE, DENY_ACCESS}};
{GENERIC_WRITE, DENY_ACCESS}
};
EXPECT_TRUE(SetEnvironmentVariableA("AZDCAP_CACHE", permission_folder));
#endif

Expand Down Expand Up @@ -859,6 +1031,49 @@ boolean RunCachePermissionTests(libary_type_t* library)
return true;
}

boolean RunCachePermissionTestsWithCustomParamToFetchCollateral(libary_type_t* library)
{
#if defined __LINUX__
auto permission_folder = "./test_permission";
int permissions[] = {0700, 0400, 0200, 0000};
setenv("AZDCAP_CACHE", permission_folder, 1);
#else
auto permission_folder = ".\\test_permission";
permission_type_t permissions[] = {
{STANDARD_RIGHTS_ALL, SET_ACCESS},
{GENERIC_READ | GENERIC_WRITE, DENY_ACCESS},
{GENERIC_READ, DENY_ACCESS},
{GENERIC_WRITE, DENY_ACCESS}
};
EXPECT_TRUE(SetEnvironmentVariableA("AZDCAP_CACHE", permission_folder));
#endif

// Create the parent folder before the library runs
for (auto permission : permissions)
{
ReloadLibrary(library);
make_folder(permission_folder, permission);
RunQuoteProviderTestsWithCustomParams(is_caching_allowed(permission));
allow_access(permission_folder);
remove_folder(permission_folder);
}

// Change the permissions on the parent folder after the
// library has used it
for (auto permission : permissions)
{
ReloadLibrary(library);
make_folder(permission_folder, permissions[0]);
RunQuoteProviderTestsWithCustomParams(true);
change_permission(permission_folder, permission);
RunQuoteProviderTestsWithCustomParams(false);
allow_access(permission_folder);
remove_folder(permission_folder);
}

return true;
}

void SetupEnvironment(std::string version)
{
#if defined __LINUX__
Expand Down Expand Up @@ -978,6 +1193,7 @@ TEST(testQuoteProv, quoteProviderTestsV3DataFromService)
SetupEnvironmentToReachSecondary();
ASSERT_TRUE(RunQuoteProviderTests());
ASSERT_TRUE(RunQuoteProviderTestsICXV3());
ASSERT_TRUE(RunQuoteProviderTestsICXV3WithParam());
ASSERT_TRUE(GetQveIdentityTest());

#if defined __LINUX__
Expand All @@ -998,6 +1214,7 @@ TEST(testQuoteProv, quoteProviderTestsV3Data)
SetupEnvironment("v3");
ASSERT_TRUE(RunQuoteProviderTests());
ASSERT_TRUE(RunQuoteProviderTestsICXV3());
ASSERT_TRUE(RunQuoteProviderTestsICXV3WithParam());
ASSERT_TRUE(GetQveIdentityTest());

#if defined __LINUX__
Expand All @@ -1017,7 +1234,7 @@ TEST(testQuoteProv, testWithoutLogging)
//
SetupEnvironment("v2");
ReloadLibrary(&library, false);
ASSERT_TRUE(RunQuoteProviderTests());
ASSERT_TRUE(RunQuoteProviderTestsWithCustomParams());
ASSERT_TRUE(GetQveIdentityTest());

#if defined __LINUX__
Expand All @@ -1036,9 +1253,30 @@ TEST(testQuoteProv, testRestrictAccessToFilesystem)
// Get the data from the service
//
SetupEnvironment("v2");
SetupEnvironmentToReachSecondary();
ReloadLibrary(&library, false);
ASSERT_TRUE(RunCachePermissionTests(&library));

#if defined __LINUX__
dlclose(library);
#else
FreeLibrary(library);
#endif
}

TEST(testQuoteProv, testRestrictAccessToFilesystemForCustomParamCollateral)
{
libary_type_t library = LoadFunctions();
ASSERT_TRUE(SGX_PLAT_ERROR_OK == sgx_ql_set_logging_function(Log));

//
// Get the data from the service
//
SetupEnvironment("v2");
SetupEnvironmentToReachSecondary();
ReloadLibrary(&library, false);
ASSERT_TRUE(RunCachePermissionTestsWithCustomParamToFetchCollateral(&library));

#if defined __LINUX__
dlclose(library);
#else
Expand Down
Loading

0 comments on commit 723a6f3

Please sign in to comment.