in network/WebSocket/WebSocketConnection.cpp [429:550]
ResponseCode WebSocketConnection::InitializeCanonicalQueryString(util::String &canonical_query_string) const {
char amz_date[MAX_LEN_FOR_UTCTIME + 1];
char date_stamp[MAX_LEN_FOR_UTCTIME + 1];
size_t date_stamp_len;
size_t amz_date_len;
{
// C Style time functions are NOT thread safe, need locking
std::lock_guard<std::mutex> time_ops_guard(time_ops_lock_);
// Get current system time
auto now = std::chrono::system_clock::now();
std::time_t current_time = std::chrono::system_clock::to_time_t(now);
// Get time, not required to free this
struct tm *curr_utc_time = gmtime(¤t_time);
if (nullptr == curr_utc_time) {
AWS_LOG_ERROR(WEBSOCKET_WRAPPER_LOG_TAG, "Failed to get UTC Date!!");
return ResponseCode::WEBSOCKET_GET_UTC_TIME_FAILED;
}
amz_date_len = std::strftime(amz_date, MAX_LEN_FOR_UTCTIME + 1, LONG_DATE_FORMAT_STR, curr_utc_time);
date_stamp_len =
std::strftime(date_stamp, MAX_LEN_FOR_UTCTIME + 1, SIMPLE_DATE_FORMAT_STR, curr_utc_time);
if (0 == amz_date_len || 0 == date_stamp_len) {
AWS_LOG_ERROR(WEBSOCKET_WRAPPER_LOG_TAG, "Failed to convert UTC date to required format!!");
return ResponseCode::WEBSOCKET_GET_UTC_TIME_FAILED;
}
AWS_LOG_DEBUG(WEBSOCKET_WRAPPER_LOG_TAG, "AmzDate: %s DateStamp: %s", amz_date, date_stamp);
}
AWS_LOG_DEBUG(WEBSOCKET_WRAPPER_LOG_TAG, "Region: %s", aws_region_.c_str());
util::String credential_scope;
util::String credential_scope_url_encode;
InitializeCredentialScope(date_stamp, date_stamp_len, credential_scope, credential_scope_url_encode);
AWS_LOG_DEBUG(WEBSOCKET_WRAPPER_LOG_TAG, "Credential Scope Url Encoded: %s",
credential_scope_url_encode.c_str());
// X-Amz-Algorithm
canonical_query_string.append(X_AMZ_ALGORITHM);
canonical_query_string.append("=");
canonical_query_string.append(AWS_HMAC_SHA256);
// X-Amz-Credential
canonical_query_string.append("&");
canonical_query_string.append(X_AMZ_CREDENTIAL);
canonical_query_string.append("=");
canonical_query_string.append(aws_access_key_id_);
canonical_query_string.append(SLASH_URLENCODE);
canonical_query_string.append(credential_scope_url_encode);
// -> X-Amz-Date
canonical_query_string.append("&");
canonical_query_string.append(X_AMZ_DATE);
canonical_query_string.append("=");
canonical_query_string.append(amz_date, amz_date_len);
// -> X-Amz-Expires
canonical_query_string.append("&");
canonical_query_string.append(X_AMZ_EXPIRES);
canonical_query_string.append("=86400");
// -> X-Amz-SignedHeaders
canonical_query_string.append("&");
canonical_query_string.append(X_AMZ_SIGNED_HEADERS);
canonical_query_string.append("=host");
AWS_LOG_DEBUG(WEBSOCKET_WRAPPER_LOG_TAG, "CanonicalQuery: %s", canonical_query_string.c_str());
// Create canonical header string
util::String canonical_headers;
canonical_headers.reserve(CANONICAL_HEADER_BUF_LEN);
canonical_headers.append("host:");
canonical_headers.append(endpoint_);
AWS_LOG_DEBUG(WEBSOCKET_WRAPPER_LOG_TAG, "CanonicalHeaders: %s", canonical_headers.c_str());
// Create canonical request
util::String canonical_request;
canonical_request.reserve(CANONICAL_REQUEST_BUF_LEN);
canonical_request.append(METHOD);
canonical_request.append("\n");
canonical_request.append(CANONICAL_URI);
canonical_request.append("\n");
canonical_request.append(canonical_query_string);
canonical_request.append("\n");
canonical_request.append(canonical_headers);
canonical_request.append("\n\nhost\n");
canonical_request.append(EMPTY_BODY_SHA256);
AWS_LOG_DEBUG(WEBSOCKET_WRAPPER_LOG_TAG, "CanonicalRequest: %s", canonical_request.c_str());
// Create string to sign
util::Vector<unsigned char> signed_str;
signed_str.resize(MAX_SIGNATURE_LEN);
unsigned int signed_string_len = 0;
InitializeSignedString(amz_date, date_stamp, date_stamp_len, amz_date_len, credential_scope,
canonical_request, signed_str, signed_string_len);
// Complete canonical query string
canonical_query_string.append("&");
canonical_query_string.append(X_AMZ_SIGNATURE);
canonical_query_string.append("=");
size_t itr;
unsigned char c;
char temp[3];
for (itr = 0; itr < signed_string_len; itr++) {
c = signed_str[itr];
snprintf(temp, 3, "%02x", c);
canonical_query_string.append(temp, 2);
}
// -> Check session token
if (0 < aws_session_token_.length()) {
canonical_query_string.append("&");
canonical_query_string.append(X_AMZ_SECURITY_TOKEN);
canonical_query_string.append("=");
util::String encoded_string = util::String(aws_session_token_);
UrlEncode(encoded_string, NOT_ENCODED_CHARS);
canonical_query_string.append(encoded_string);
}
AWS_LOG_DEBUG(WEBSOCKET_WRAPPER_LOG_TAG, "CompletedCanonicalQuery: %s", canonical_query_string.c_str());
return ResponseCode::SUCCESS;
}