-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calling into thim agent to get collateral. #149
base: master
Are you sure you want to change the base?
Changes from 2 commits
45d7779
0e3688b
a8e56e8
d7c727c
dcc249b
81fb0bc
734a3e4
6e56c7b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,7 +70,7 @@ char const* curl_easy::error::what() const noexcept | |
/////////////////////////////////////////////////////////////////////////////// | ||
// curl_easy implementation | ||
/////////////////////////////////////////////////////////////////////////////// | ||
std::unique_ptr<curl_easy> curl_easy::create(const std::string& url, const std::string* const p_body) | ||
std::unique_ptr<curl_easy> curl_easy::create(const std::string& url, const std::string* const p_body, LPCWSTR httpVerb)) | ||
{ | ||
std::unique_ptr<curl_easy> easy(new curl_easy); | ||
|
||
|
@@ -92,7 +92,12 @@ std::unique_ptr<curl_easy> curl_easy::create(const std::string& url, const std:: | |
|
||
if (p_body != nullptr && !p_body->empty()) | ||
{ | ||
easy->set_opt_or_throw(CURLOPT_CUSTOMREQUEST, "GET"); | ||
if (httpVerb == L"POST") { | ||
msft-gumunjal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
easy->set_opt_or_throw(CURLOPT_POST, 1L); | ||
} | ||
else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if we have a style checker integrated into the VS solution. If we do and it passes, then ignore this comment. The convention I see in other parts of the file is to throw opening curly braces on the line after the if/else statement. We should probably keep doing that to stay consistent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont think we have a style checker. Let me try to add one. |
||
easy->set_opt_or_throw(CURLOPT_HTTPGET, 1L); | ||
} | ||
easy->set_opt_or_throw(CURLOPT_COPYPOSTFIELDS, p_body->c_str()); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -54,12 +54,15 @@ static const std::map<std::string, std::string> default_values = { | |||||
// New API version used to request PEM encoded CRLs | ||||||
constexpr char API_VERSION_LEGACY[] = "api-version=2018-10-01-preview"; | ||||||
constexpr char API_VERSION[] = "api-version=2020-02-12-preview"; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have a new API version for the THIM Agent APIs. However, I want to confirm -- what format CRL does Azure DCAP want now? It says 'New API version used to request PEM encoded CRLs', but I recall Shiv saying the new versions of DCAP expect DER, so I'm a bit confused.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Scratch that. I think what you might want to do is: You can use the new API version for the GetCert calls, and the existing API versions for the other collateral. |
||||||
|
||||||
static char DEFAULT_CERT_URL[] = | ||||||
"https://global.acccache.azure.net/sgx/certificates"; | ||||||
"https://global.acccache.azure.net/sgx/certificates/"; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once THIM Service deploys new controller to align with Intel, this should be updated. The final URL will be like: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed! I coded this based on the current prod code. Will update this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new URL is available now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey guys -- I see we've changed from certificates to "certification" -- in the last correspondence I read I saw There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No change needed, certificates is fine here. |
||||||
static std::string cert_base_url = DEFAULT_CERT_URL; | ||||||
|
||||||
static char DEFAULT_CLIENT_ID[] = "production_client"; | ||||||
static char DEFAULT_THIM_AGENT_URL[] = | ||||||
"http://169.254.169.254/metadata/THIM/sgx/getCerts?"; | ||||||
msft-gumunjal marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
static std::string thim_agent_base_url = DEFAULT_THIM_AGENT_URL; | ||||||
|
||||||
static char DEFAULT_CLIENT_ID[] = "Azure DCAP_client"; | ||||||
msft-gumunjal marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
static std::string prod_client_id = DEFAULT_CLIENT_ID; | ||||||
|
||||||
static char DEFAULT_COLLATERAL_VERSION[] = "v3"; | ||||||
|
@@ -135,6 +138,25 @@ static std::string get_collateral_version() | |||||
} | ||||||
} | ||||||
|
||||||
static std::string get_agent_base_url() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this function necessary? It made sense with THIM cloud service because we could test different cloud endpoints (e.g. Europe vs. Americas). But THIM Agent will always be hosted at the same local IP address. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this will be useful for dev box testing with IMDS and THIM agent running on the dev box. |
||||||
{ | ||||||
std::string env_base_url = get_env_variable(ENV_AZDCAP_THIM_AGENT_URL); | ||||||
|
||||||
if (env_base_url.empty()) | ||||||
{ | ||||||
log(SGX_QL_LOG_WARNING, | ||||||
"Using default THIM Agent base cert URL '%s'.", | ||||||
thim_agent_base_url.c_str()); | ||||||
return thim_agent_base_url; | ||||||
} | ||||||
|
||||||
log(SGX_QL_LOG_INFO, | ||||||
"Using %s envvar for base cert URL, set to '%s'.", | ||||||
ENV_AZDCAP_THIM_AGENT_URL, | ||||||
env_base_url.c_str()); | ||||||
return env_base_url; | ||||||
} | ||||||
|
||||||
static std::string get_base_url() | ||||||
{ | ||||||
std::string env_base_url = get_env_variable(ENV_AZDCAP_BASE_URL); | ||||||
|
@@ -456,10 +478,9 @@ void safe_cast(input_t in, output_t* out) | |||||
*out = static_cast<output_t>(in); | ||||||
} | ||||||
|
||||||
// | ||||||
// Build up the URL needed to fetch specific certificate information. | ||||||
// | ||||||
static std::string build_pck_cert_url(const sgx_ql_pck_cert_id_t& pck_cert_id) | ||||||
static void build_pck_cert_url( | ||||||
const sgx_ql_pck_cert_id_t& pck_cert_id, | ||||||
collateral_fetch_url* collateral_url) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the part im referencing below. It doesn't seem legacy, it seems like you've introduced it? |
||||||
{ | ||||||
const std::string qe_id = | ||||||
format_as_hex_string(pck_cert_id.p_qe3_id, pck_cert_id.qe3_id_size); | ||||||
|
@@ -473,28 +494,34 @@ static std::string build_pck_cert_url(const sgx_ql_pck_cert_id_t& pck_cert_id) | |||||
|
||||||
const std::string pce_id = | ||||||
format_as_big_endian_hex_string(pck_cert_id.pce_id); | ||||||
|
||||||
std::string version = get_collateral_version(); | ||||||
std::stringstream pck_cert_url; | ||||||
pck_cert_url << get_base_url(); | ||||||
|
||||||
collateral_url->thim_service_url << get_base_url(); | ||||||
collateral_url->thim_service_url << "noauth/pckcertificate?"; | ||||||
collateral_url->thim_agent_url << get_agent_base_url(); | ||||||
|
||||||
if (!version.empty()) | ||||||
{ | ||||||
pck_cert_url << '/'; | ||||||
pck_cert_url << version; | ||||||
collateral_url->thim_service_url << "version=" << version << '&'; | ||||||
collateral_url->thim_agent_url << "TEEVersionType=" << version << '&'; | ||||||
} | ||||||
pck_cert_url << '/' << qe_id; | ||||||
pck_cert_url << '/' << cpu_svn; | ||||||
pck_cert_url << '/' << pce_svn; | ||||||
pck_cert_url << '/' << pce_id; | ||||||
pck_cert_url << '?'; | ||||||
collateral_url->thim_service_url << "qeid=" << qe_id << '&'; | ||||||
collateral_url->thim_service_url << "cpusvn=" << cpu_svn << '&'; | ||||||
collateral_url->thim_service_url << "pcesvn=" << pce_svn << '&'; | ||||||
collateral_url->thim_service_url << "pceid=" << pce_id << '&'; | ||||||
|
||||||
collateral_url->thim_agent_url << "qeid=" << qe_id << '&'; | ||||||
collateral_url->thim_agent_url << "cpusvn=" << cpu_svn << '&'; | ||||||
collateral_url->thim_agent_url << "pcesvn=" << pce_svn << '&'; | ||||||
collateral_url->thim_agent_url << "pceid=" << pce_id; | ||||||
|
||||||
std::string client_id = get_client_id(); | ||||||
|
||||||
if (!client_id.empty()) | ||||||
{ | ||||||
pck_cert_url << "clientid=" << client_id << '&'; | ||||||
collateral_url->thim_service_url << "clientid=" << client_id << '&'; | ||||||
} | ||||||
pck_cert_url << API_VERSION_LEGACY; | ||||||
return pck_cert_url.str(); | ||||||
collateral_url->thim_service_url << API_VERSION_LEGACY; | ||||||
} | ||||||
|
||||||
// | ||||||
|
@@ -897,31 +924,80 @@ extern "C" quote3_error_t sgx_ql_get_quote_config( | |||||
|
||||||
try | ||||||
{ | ||||||
const std::string cert_url = build_pck_cert_url(*p_pck_cert_id); | ||||||
if (auto cache_hit = try_cache_get(cert_url)) | ||||||
collateral_fetch_url collateral_url; | ||||||
build_pck_cert_url(*p_pck_cert_id, &collateral_url); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason this was done as a pointer instead of just as a reference? Why not just use it as a reference? Your end result is the same but you don't end up having to worry about NULL issues and it seems like your goal is to update the existing variable here so my recommendation is to pass by reference. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part of code was already there. I don't want to change whats already there, just adding functionality to call into THIM agent in this PR There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added another comment above to indicate what I think you're adding in. Please let me know if I have some misunderstanding. |
||||||
std::string cert_url = collateral_url.thim_service_url.str(); | ||||||
std::string thim_agent_url = collateral_url.thim_agent_url.str(); | ||||||
std::unique_ptr<curl_easy> curl; | ||||||
bool thim_agent_success = true; | ||||||
msft-gumunjal marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
try | ||||||
{ | ||||||
curl = curl_easy::create(thim_agent_url, NULL); | ||||||
log(SGX_QL_LOG_INFO, | ||||||
"Fetching quote config from cache: '%s'.", | ||||||
cert_url.c_str()); | ||||||
"Fetching quote config from THIM agent server: '%s'.", | ||||||
thim_agent_url.c_str()); | ||||||
curl->set_headers(headers::default_values); | ||||||
curl->perform(); | ||||||
} | ||||||
catch (const std::bad_alloc&) | ||||||
{ | ||||||
log_message(SGX_QL_LOG_ERROR, "Out of memory thrown"); | ||||||
thim_agent_success = false; | ||||||
return SGX_QL_ERROR_OUT_OF_MEMORY; | ||||||
} | ||||||
catch (const std::runtime_error& error) | ||||||
{ | ||||||
log(SGX_QL_LOG_WARNING, | ||||||
"Runtime exception thrown, error: %s", | ||||||
error.what()); | ||||||
thim_agent_success = false; | ||||||
// Swallow adding file to cache. Library can | ||||||
// operate without caching | ||||||
// return SGX_QL_ERROR_UNEXPECTED; | ||||||
msft-gumunjal marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
} | ||||||
catch (const std::exception& error) | ||||||
{ | ||||||
log(SGX_QL_LOG_ERROR, | ||||||
"Unknown exception thrown, error: %s", | ||||||
error.what()); | ||||||
thim_agent_success = false; | ||||||
//return SGX_QL_ERROR_UNEXPECTED; | ||||||
} | ||||||
catch (const curl_easy::error& error) | ||||||
{ | ||||||
log(SGX_QL_LOG_ERROR, | ||||||
"error thrown, error code: %x: %s", | ||||||
error.code, | ||||||
error.what()); | ||||||
thim_agent_success = false; | ||||||
} | ||||||
if (!thim_agent_success) { | ||||||
if (auto cache_hit = try_cache_get(cert_url)) | ||||||
{ | ||||||
log(SGX_QL_LOG_INFO, | ||||||
"Fetching quote config from cache: '%s'.", | ||||||
cert_url.c_str()); | ||||||
|
||||||
*pp_quote_config = | ||||||
(sgx_ql_config_t*)(new uint8_t[cache_hit->size()]); | ||||||
memcpy(*pp_quote_config, cache_hit->data(), cache_hit->size()); | ||||||
*pp_quote_config = | ||||||
(sgx_ql_config_t*)(new uint8_t[cache_hit->size()]); | ||||||
memcpy(*pp_quote_config, cache_hit->data(), cache_hit->size()); | ||||||
|
||||||
// re-aligning the p_cert_data pointer | ||||||
(*pp_quote_config)->p_cert_data = | ||||||
(uint8_t*)(*pp_quote_config) + sizeof(sgx_ql_config_t); | ||||||
// re-aligning the p_cert_data pointer | ||||||
(*pp_quote_config)->p_cert_data = | ||||||
(uint8_t*)(*pp_quote_config) + sizeof(sgx_ql_config_t); | ||||||
|
||||||
return SGX_QL_SUCCESS; | ||||||
return SGX_QL_SUCCESS; | ||||||
} | ||||||
|
||||||
const std::string eppid_json = build_eppid_json(*p_pck_cert_id); | ||||||
curl = curl_easy::create(cert_url, &eppid_json, L"POST"); | ||||||
log(SGX_QL_LOG_INFO, | ||||||
"Fetching quote config from remote server: '%s'.", | ||||||
cert_url.c_str()); | ||||||
curl->set_headers(headers::default_values); | ||||||
curl->perform(); | ||||||
} | ||||||
|
||||||
const std::string eppid_json = build_eppid_json(*p_pck_cert_id); | ||||||
const auto curl = curl_easy::create(cert_url, &eppid_json); | ||||||
log(SGX_QL_LOG_INFO, | ||||||
"Fetching quote config from remote server: '%s'.", | ||||||
cert_url.c_str()); | ||||||
curl->set_headers(headers::default_values); | ||||||
curl->perform(); | ||||||
|
||||||
// we better get TCB info and the cert chain, else we cannot provide the | ||||||
// required data to the caller. | ||||||
|
@@ -977,7 +1053,7 @@ extern "C" quote3_error_t sgx_ql_get_quote_config( | |||||
*curl, headers::CACHE_CONTROL, &cache_control); | ||||||
|
||||||
auto retval = convert_to_intel_error(get_cache_header_operation); | ||||||
if (retval == SGX_QL_SUCCESS) | ||||||
if ((retval == SGX_QL_SUCCESS) and (!thim_agent_success)) | ||||||
msft-gumunjal marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{ | ||||||
time_t expiry; | ||||||
if (get_cache_expiration_time(cache_control, cert_url, expiry)) | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, why use
LPCWSTR
instead ofconst std::string&
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main reason for this file is to keep the structure consistent with the other curl_easy.cpp file(in src/Windows). The variable is used by "WinHttpOpenRequest" in src/Windows/curl_easy.cpp file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is Linux specific. Other parameters are std::string, so not appreciating the need for consistency with the windows version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This parameter is used by "WinHttpOpenRequest" and the data type is supposed to be "LPCWSTR". Either I can pass a string to the function and then convert it inside the function or just pass the desired data type. I chose the latter one because I thought that's the better out of the two. I can update if required.