in cvm-securekey-release-app/AttestationUtil.cpp [556:705]
std::string Util::GetKeyVaultResponse(const std::string &requestUri,
const std::string &access_token,
const std::string &attestation_token,
const std::string &nonce)
{
TRACE_OUT("Entering Util::GetKeyVaultResponse()");
CURL *curl = curl_easy_init();
if (!curl)
{
TRACE_ERROR_EXIT("curl_easy_init() failed")
}
CURLcode curlRet = curl_easy_setopt(curl, CURLOPT_URL, requestUri.c_str());
if (curlRet != CURLE_OK)
{
TRACE_ERROR_EXIT("curl_easy_setopt() failed for URL")
}
curlRet = curl_easy_setopt(curl, CURLOPT_POST, 1L);
if (curlRet != CURLE_OK)
{
TRACE_ERROR_EXIT("curl_easy_setopt() failed for POST")
}
curlRet = curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
if (curlRet != CURLE_OK)
{
TRACE_ERROR_EXIT("curl_easy_setopt() failed for HTTP_VERSION")
}
struct curl_slist *headers = NULL;
std::ostringstream bearerToken;
bearerToken << "Authorization: Bearer " << access_token;
headers = curl_slist_append(headers, bearerToken.str().c_str());
TRACE_OUT("Bearer token: %s", Util::reduct_log(bearerToken.str()).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "User-Agent: AzureDiskEncryption");
curlRet = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
if (curlRet != CURLE_OK)
{
TRACE_ERROR_EXIT("curl_easy_setopt() failed\n")
}
std::ostringstream requestBody;
std::string nonce_token;
nonce_token.assign(nonce);
if (nonce_token.empty())
{
// use some random nonce
nonce_token.assign(Constants::NONCE);
}
requestBody << "{";
requestBody << "\"nonce\": \"" + nonce_token + "\",";
requestBody << "\"target\": \"" << attestation_token << "\",";
requestBody << "\"enc\": \"CKM_RSA_AES_KEY_WRAP\"";
requestBody << "}";
std::string requestBodyStr(requestBody.str());
// TRACE_OUT("requestBody: size=%d, '%s'", requestBodyStr.size(), requestBodyStr.c_str());
curlRet = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBodyStr.c_str());
if (curlRet != CURLE_OK)
{
TRACE_ERROR_EXIT("curl_easy_setopt() failed for CURLOPT_POSTFIELDS\n")
}
curlRet = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)requestBodyStr.size());
if (curlRet != CURLE_OK)
{
TRACE_ERROR_EXIT("curl_easy_setopt() failed for CURLOPT_POSTFIELDSIZE\n")
}
// Enable verbose output from curl for debugging.
/*
curlRet = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
if (curlRet != CURLE_OK)
{
TRACE_ERROR_EXIT("curl_easy_setopt() failed for CURLOPT_VERBOSE\n")
}
*/
char errbuf[CURL_ERROR_SIZE] = {
0,
};
curlRet = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
if (curlRet != CURLE_OK)
{
size_t len = strlen(errbuf);
std::cerr << "libcurl: " << curlRet << std::endl;
if (len)
std::cerr << errbuf << (errbuf[len - 1] != '\n') ? "\n" : "";
std::cerr << curl_easy_strerror(curlRet) << std::endl;
TRACE_ERROR_EXIT("curl_easy_setopt() failed for CURLOPT_ERRORBUFFER\n")
}
// DEBUG only, when a proxy is needed such as Fiddler.
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curlRet = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteCallback);
if (curlRet != CURLE_OK)
{
TRACE_ERROR_EXIT("curl_easy_setopt() failed")
}
#ifndef PLATFORM_UNIX
curl_easy_setopt(curl, CURLOPT_CAINFO, "curl-ca-bundle.crt");
#endif
std::string responseStr;
curlRet = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseStr);
if (curlRet != CURLE_OK)
{
std::ostringstream oss;
oss << "curl_easy_setopt() failed: " << curl_easy_strerror(curlRet);
TRACE_ERROR_EXIT(oss.str().c_str())
}
// Perform the request, check the return code
curlRet = curl_easy_perform(curl);
// Check for errors
if (curlRet != CURLE_OK)
{
std::ostringstream oss;
oss << "curl_easy_perform() failed: " << curl_easy_strerror(curlRet);
TRACE_ERROR_EXIT(oss.str().c_str())
}
/*
switch (code) {
case CURLE_COULDNT_RESOLVE_HOST:
case CURLE_COULDNT_RESOLVE_PROXY:
case CURLE_COULDNT_CONNECT:
case CURLE_WRITE_ERROR:
STATSCOUNTER_INC(indexConFail, mutIndexConFail);
return RS_RET_SUSPENDED;
default:
STATSCOUNTER_INC(indexSubmit, mutIndexSubmit);
return RS_RET_OK;
}
*/
// Cleanup curl
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
TRACE_OUT("SKR response: %s", Util::reduct_log(responseStr).c_str());
TRACE_OUT("Exiting Util::GetKeyVaultResponse()");
return responseStr;
}