aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth
diff options
context:
space:
mode:
authordakovalkov <dakovalkov@yandex-team.com>2023-12-03 13:33:55 +0300
committerdakovalkov <dakovalkov@yandex-team.com>2023-12-03 14:04:39 +0300
commit2a718325637e5302334b6d0a6430f63168f8dbb3 (patch)
tree64be81080b7df9ec1d86d053a0c394ae53fcf1fe /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth
parente0d94a470142d95c3007e9c5d80380994940664a (diff)
downloadydb-2a718325637e5302334b6d0a6430f63168f8dbb3.tar.gz
Update contrib/libs/aws-sdk-cpp to 1.11.37
Diffstat (limited to 'contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth')
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp806
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp74
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp6
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp32
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp11
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp35
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp244
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp46
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp (renamed from contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp)13
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp50
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp320
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp14
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp103
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp580
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp14
15 files changed, 1508 insertions, 840 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp
deleted file mode 100644
index 0baa00058f..0000000000
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSigner.cpp
+++ /dev/null
@@ -1,806 +0,0 @@
-/**
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0.
- */
-
-#include <aws/core/auth/AWSAuthSigner.h>
-
-#include <aws/core/auth/AWSCredentialsProvider.h>
-#include <aws/core/client/ClientConfiguration.h>
-#include <aws/core/http/HttpRequest.h>
-#include <aws/core/http/HttpResponse.h>
-#include <aws/core/utils/DateTime.h>
-#include <aws/core/utils/HashingUtils.h>
-#include <aws/core/utils/Outcome.h>
-#include <aws/core/utils/StringUtils.h>
-#include <aws/core/utils/logging/LogMacros.h>
-#include <aws/core/utils/memory/AWSMemory.h>
-#include <aws/core/utils/crypto/Sha256.h>
-#include <aws/core/utils/crypto/Sha256HMAC.h>
-#include <aws/core/utils/stream/PreallocatedStreamBuf.h>
-#include <aws/core/utils/event/EventMessage.h>
-#include <aws/core/utils/event/EventHeader.h>
-
-#include <cstdio>
-#include <iomanip>
-#include <math.h>
-#include <cstring>
-
-using namespace Aws;
-using namespace Aws::Client;
-using namespace Aws::Auth;
-using namespace Aws::Http;
-using namespace Aws::Utils;
-using namespace Aws::Utils::Logging;
-
-static const char* EQ = "=";
-static const char* AWS_HMAC_SHA256 = "AWS4-HMAC-SHA256";
-static const char* EVENT_STREAM_CONTENT_SHA256 = "STREAMING-AWS4-HMAC-SHA256-EVENTS";
-static const char* EVENT_STREAM_PAYLOAD = "AWS4-HMAC-SHA256-PAYLOAD";
-static const char* AWS4_REQUEST = "aws4_request";
-static const char* SIGNED_HEADERS = "SignedHeaders";
-static const char* CREDENTIAL = "Credential";
-static const char* NEWLINE = "\n";
-static const char* X_AMZ_SIGNED_HEADERS = "X-Amz-SignedHeaders";
-static const char* X_AMZ_ALGORITHM = "X-Amz-Algorithm";
-static const char* X_AMZ_CREDENTIAL = "X-Amz-Credential";
-static const char* UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
-static const char* X_AMZ_SIGNATURE = "X-Amz-Signature";
-static const char* X_AMZN_TRACE_ID = "x-amzn-trace-id";
-static const char* X_AMZ_CONTENT_SHA256 = "x-amz-content-sha256";
-static const char* USER_AGENT = "user-agent";
-static const char* SIGNING_KEY = "AWS4";
-static const char* SIMPLE_DATE_FORMAT_STR = "%Y%m%d";
-static const char* EMPTY_STRING_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
-
-static const char v4LogTag[] = "AWSAuthV4Signer";
-static const char v4StreamingLogTag[] = "AWSAuthEventStreamV4Signer";
-
-namespace Aws
-{
- namespace Auth
- {
- const char SIGNATURE[] = "Signature";
- const char SIGV4_SIGNER[] = "SignatureV4";
- const char EVENTSTREAM_SIGV4_SIGNER[] = "EventStreamSignatureV4";
- const char EVENTSTREAM_SIGNATURE_HEADER[] = ":chunk-signature";
- const char EVENTSTREAM_DATE_HEADER[] = ":date";
- const char NULL_SIGNER[] = "NullSigner";
- }
-}
-
-static Aws::String CanonicalizeRequestSigningString(HttpRequest& request, bool urlEscapePath)
-{
- request.CanonicalizeRequest();
- Aws::StringStream signingStringStream;
- signingStringStream << HttpMethodMapper::GetNameForHttpMethod(request.GetMethod());
-
- URI uriCpy = request.GetUri();
- // Many AWS services do not decode the URL before calculating SignatureV4 on their end.
- // This results in the signature getting calculated with a double encoded URL.
- // That means we have to double encode it here for the signature to match on the service side.
- if(urlEscapePath)
- {
- // RFC3986 is how we encode the URL before sending it on the wire.
- auto rfc3986EncodedPath = URI::URLEncodePathRFC3986(uriCpy.GetPath());
- uriCpy.SetPath(rfc3986EncodedPath);
- // However, SignatureV4 uses this URL encoding scheme
- signingStringStream << NEWLINE << uriCpy.GetURLEncodedPath() << NEWLINE;
- }
- else
- {
- // For the services that DO decode the URL first; we don't need to double encode it.
- uriCpy.SetPath(uriCpy.GetURLEncodedPath());
- signingStringStream << NEWLINE << uriCpy.GetPath() << NEWLINE;
- }
-
- if (request.GetQueryString().find('=') != std::string::npos)
- {
- signingStringStream << request.GetQueryString().substr(1) << NEWLINE;
- }
- else if (request.GetQueryString().size() > 1)
- {
- signingStringStream << request.GetQueryString().substr(1) << "=" << NEWLINE;
- }
- else
- {
- signingStringStream << NEWLINE;
- }
-
- return signingStringStream.str();
-}
-
-static Http::HeaderValueCollection CanonicalizeHeaders(Http::HeaderValueCollection&& headers)
-{
- Http::HeaderValueCollection canonicalHeaders;
- for (const auto& header : headers)
- {
- auto trimmedHeaderName = StringUtils::Trim(header.first.c_str());
- auto trimmedHeaderValue = StringUtils::Trim(header.second.c_str());
-
- //multiline gets converted to line1,line2,etc...
- auto headerMultiLine = StringUtils::SplitOnLine(trimmedHeaderValue);
- Aws::String headerValue = headerMultiLine.size() == 0 ? "" : headerMultiLine[0];
-
- if (headerMultiLine.size() > 1)
- {
- for(size_t i = 1; i < headerMultiLine.size(); ++i)
- {
- headerValue += ",";
- headerValue += StringUtils::Trim(headerMultiLine[i].c_str());
- }
- }
-
- //duplicate spaces need to be converted to one.
- Aws::String::iterator new_end =
- std::unique(headerValue.begin(), headerValue.end(),
- [=](char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }
- );
- headerValue.erase(new_end, headerValue.end());
-
- canonicalHeaders[trimmedHeaderName] = headerValue;
- }
-
- return canonicalHeaders;
-}
-
-AWSAuthV4Signer::AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider,
- const char* serviceName, const Aws::String& region, PayloadSigningPolicy signingPolicy, bool urlEscapePath) :
- m_includeSha256HashHeader(true),
- m_credentialsProvider(credentialsProvider),
- m_serviceName(serviceName),
- m_region(region),
- m_hash(Aws::MakeUnique<Aws::Utils::Crypto::Sha256>(v4LogTag)),
- m_HMAC(Aws::MakeUnique<Aws::Utils::Crypto::Sha256HMAC>(v4LogTag)),
- m_unsignedHeaders({USER_AGENT, X_AMZN_TRACE_ID}),
- m_payloadSigningPolicy(signingPolicy),
- m_urlEscapePath(urlEscapePath)
-{
- //go ahead and warm up the signing cache.
- ComputeHash(credentialsProvider->GetAWSCredentials().GetAWSSecretKey(), DateTime::CalculateGmtTimestampAsString(SIMPLE_DATE_FORMAT_STR), region, m_serviceName);
-}
-
-AWSAuthV4Signer::~AWSAuthV4Signer()
-{
- // empty destructor in .cpp file to keep from needing the implementation of (AWSCredentialsProvider, Sha256, Sha256HMAC) in the header file
-}
-
-
-bool AWSAuthV4Signer::ShouldSignHeader(const Aws::String& header) const
-{
- return m_unsignedHeaders.find(Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend();
-}
-
-bool AWSAuthV4Signer::SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const
-{
- AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials();
-
- //don't sign anonymous requests
- if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty())
- {
- return true;
- }
-
- if (!credentials.GetSessionToken().empty())
- {
- request.SetAwsSessionToken(credentials.GetSessionToken());
- }
-
- Aws::String payloadHash(UNSIGNED_PAYLOAD);
- switch(m_payloadSigningPolicy)
- {
- case PayloadSigningPolicy::Always:
- signBody = true;
- break;
- case PayloadSigningPolicy::Never:
- signBody = false;
- break;
- case PayloadSigningPolicy::RequestDependent:
- // respect the request setting
- default:
- break;
- }
-
- if(signBody || request.GetUri().GetScheme() != Http::Scheme::HTTPS)
- {
- payloadHash = ComputePayloadHash(request);
- if (payloadHash.empty())
- {
- return false;
- }
- }
- else
- {
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Note: Http payloads are not being signed. signPayloads=" << signBody
- << " http scheme=" << Http::SchemeMapper::ToString(request.GetUri().GetScheme()));
- }
-
- if(m_includeSha256HashHeader)
- {
- request.SetHeaderValue(X_AMZ_CONTENT_SHA256, payloadHash);
- }
-
- //calculate date header to use in internal signature (this also goes into date header).
- DateTime now = GetSigningTimestamp();
- Aws::String dateHeaderValue = now.ToGmtString(DateFormat::ISO_8601_BASIC);
- request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue);
-
- Aws::StringStream headersStream;
- Aws::StringStream signedHeadersStream;
-
- for (const auto& header : CanonicalizeHeaders(request.GetHeaders()))
- {
- if(ShouldSignHeader(header.first))
- {
- headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE;
- signedHeadersStream << header.first.c_str() << ";";
- }
- }
-
- Aws::String canonicalHeadersString = headersStream.str();
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString);
-
- //calculate signed headers parameter
- Aws::String signedHeadersValue = signedHeadersStream.str();
- //remove that last semi-colon
- if (!signedHeadersValue.empty())
- {
- signedHeadersValue.pop_back();
- }
-
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value:" << signedHeadersValue);
-
- //generate generalized canonicalized request string.
- Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, m_urlEscapePath);
-
- //append v4 stuff to the canonical request string.
- canonicalRequestString.append(canonicalHeadersString);
- canonicalRequestString.append(NEWLINE);
- canonicalRequestString.append(signedHeadersValue);
- canonicalRequestString.append(NEWLINE);
- canonicalRequestString.append(payloadHash);
-
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString);
-
- //now compute sha256 on that request string
- auto hashResult = m_hash->Calculate(canonicalRequestString);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string");
- AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\"");
- return false;
- }
-
- auto sha256Digest = hashResult.GetResult();
- Aws::String canonicalRequestHash = HashingUtils::HexEncode(sha256Digest);
- Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR);
-
- Aws::String signingRegion = region ? region : m_region;
- Aws::String signingServiceName = serviceName ? serviceName : m_serviceName;
- Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName);
- auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName);
-
- Aws::StringStream ss;
- ss << AWS_HMAC_SHA256 << " " << CREDENTIAL << EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate
- << "/" << signingRegion << "/" << signingServiceName << "/" << AWS4_REQUEST << ", " << SIGNED_HEADERS << EQ
- << signedHeadersValue << ", " << SIGNATURE << EQ << finalSignature;
-
- auto awsAuthString = ss.str();
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Signing request with: " << awsAuthString);
- request.SetAwsAuthorization(awsAuthString);
- request.SetSigningAccessKey(credentials.GetAWSAccessKeyId());
- request.SetSigningRegion(signingRegion);
- return true;
-}
-
-bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, long long expirationTimeInSeconds) const
-{
- return PresignRequest(request, m_region.c_str(), expirationTimeInSeconds);
-}
-
-bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds) const
-{
- return PresignRequest(request, region, m_serviceName.c_str(), expirationInSeconds);
-}
-
-bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationTimeInSeconds) const
-{
- AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials();
-
- //don't sign anonymous requests
- if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty())
- {
- return true;
- }
-
- Aws::StringStream intConversionStream;
- intConversionStream << expirationTimeInSeconds;
- request.AddQueryStringParameter(Http::X_AMZ_EXPIRES_HEADER, intConversionStream.str());
-
- if (!credentials.GetSessionToken().empty())
- {
- request.AddQueryStringParameter(Http::AWS_SECURITY_TOKEN, credentials.GetSessionToken());
- }
-
- //calculate date header to use in internal signature (this also goes into date header).
- DateTime now = GetSigningTimestamp();
- Aws::String dateQueryValue = now.ToGmtString(DateFormat::ISO_8601_BASIC);
- request.AddQueryStringParameter(Http::AWS_DATE_HEADER, dateQueryValue);
-
- Aws::StringStream headersStream;
- Aws::StringStream signedHeadersStream;
- for (const auto& header : CanonicalizeHeaders(request.GetHeaders()))
- {
- if(ShouldSignHeader(header.first))
- {
- headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE;
- signedHeadersStream << header.first.c_str() << ";";
- }
- }
-
- Aws::String canonicalHeadersString = headersStream.str();
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString);
-
- //calculate signed headers parameter
- Aws::String signedHeadersValue(signedHeadersStream.str());
- //remove that last semi-colon
- if (!signedHeadersValue.empty())
- {
- signedHeadersValue.pop_back();
- }
-
- request.AddQueryStringParameter(X_AMZ_SIGNED_HEADERS, signedHeadersValue);
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value: " << signedHeadersValue);
-
- Aws::StringStream ss;
- Aws::String signingRegion = region ? region : m_region;
- Aws::String signingServiceName = serviceName ? serviceName : m_serviceName;
- Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR);
- ss << credentials.GetAWSAccessKeyId() << "/" << simpleDate
- << "/" << signingRegion << "/" << signingServiceName << "/" << AWS4_REQUEST;
-
- request.AddQueryStringParameter(X_AMZ_ALGORITHM, AWS_HMAC_SHA256);
- request.AddQueryStringParameter(X_AMZ_CREDENTIAL, ss.str());
- ss.str("");
-
- request.SetSigningAccessKey(credentials.GetAWSAccessKeyId());
- request.SetSigningRegion(signingRegion);
-
- //generate generalized canonicalized request string.
- Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, m_urlEscapePath);
-
- //append v4 stuff to the canonical request string.
- canonicalRequestString.append(canonicalHeadersString);
- canonicalRequestString.append(NEWLINE);
- canonicalRequestString.append(signedHeadersValue);
- canonicalRequestString.append(NEWLINE);
- if (ServiceRequireUnsignedPayload(signingServiceName))
- {
- canonicalRequestString.append(UNSIGNED_PAYLOAD);
- }
- else
- {
- canonicalRequestString.append(EMPTY_STRING_SHA256);
- }
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString);
-
- //now compute sha256 on that request string
- auto hashResult = m_hash->Calculate(canonicalRequestString);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string");
- AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\"");
- return false;
- }
-
- auto sha256Digest = hashResult.GetResult();
- auto canonicalRequestHash = HashingUtils::HexEncode(sha256Digest);
-
- auto stringToSign = GenerateStringToSign(dateQueryValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName);
- auto finalSigningHash = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName);
- if (finalSigningHash.empty())
- {
- return false;
- }
-
- //add that the signature to the query string
- request.AddQueryStringParameter(X_AMZ_SIGNATURE, finalSigningHash);
-
- return true;
-}
-
-bool AWSAuthV4Signer::ServiceRequireUnsignedPayload(const Aws::String& serviceName) const
-{
- // S3 uses a magic string (instead of the empty string) for its body hash for presigned URLs as outlined here:
- // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
- // this is true for PUT, POST, GET, DELETE and HEAD operations.
- // However, other services (for example RDS) implement the specification as outlined here:
- // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
- // which states that body-less requests should use the empty-string SHA256 hash.
- return "s3" == serviceName || "s3-object-lambda" == serviceName;
-}
-
-Aws::String AWSAuthV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign,
- const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const
-{
- auto key = ComputeHash(credentials.GetAWSSecretKey(), simpleDate, region, serviceName);
- return GenerateSignature(stringToSign, key);
-}
-
-Aws::String AWSAuthV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const
-{
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Final String to sign: " << stringToSign);
-
- Aws::StringStream ss;
-
- auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hmac (sha256) final string");
- AWS_LOGSTREAM_DEBUG(v4LogTag, "The final string is: \"" << stringToSign << "\"");
- return {};
- }
-
- //now we finally sign our request string with our hex encoded derived hash.
- auto finalSigningDigest = hashResult.GetResult();
-
- auto finalSigningHash = HashingUtils::HexEncode(finalSigningDigest);
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Final computed signing hash: " << finalSigningHash);
-
- return finalSigningHash;
-}
-
-Aws::String AWSAuthV4Signer::ComputePayloadHash(Aws::Http::HttpRequest& request) const
-{
- if (!request.GetContentBody())
- {
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Using cached empty string sha256 " << EMPTY_STRING_SHA256 << " because payload is empty.");
- return EMPTY_STRING_SHA256;
- }
-
- //compute hash on payload if it exists.
- auto hashResult = m_hash->Calculate(*request.GetContentBody());
-
- if(request.GetContentBody())
- {
- request.GetContentBody()->clear();
- request.GetContentBody()->seekg(0);
- }
-
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hash (sha256) request body");
- return {};
- }
-
- auto sha256Digest = hashResult.GetResult();
-
- Aws::String payloadHash(HashingUtils::HexEncode(sha256Digest));
- AWS_LOGSTREAM_DEBUG(v4LogTag, "Calculated sha256 " << payloadHash << " for payload.");
- return payloadHash;
-}
-
-Aws::String AWSAuthV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate,
- const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const
-{
- //generate the actual string we will use in signing the final request.
- Aws::StringStream ss;
-
- ss << AWS_HMAC_SHA256 << NEWLINE << dateValue << NEWLINE << simpleDate << "/" << region << "/"
- << serviceName << "/" << AWS4_REQUEST << NEWLINE << canonicalRequestHash;
-
- return ss.str();
-}
-
-Aws::Utils::ByteBuffer AWSAuthV4Signer::ComputeHash(const Aws::String& secretKey,
- const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const
-{
- Aws::String signingKey(SIGNING_KEY);
- signingKey.append(secretKey);
- auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()),
- ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length()));
-
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\"");
- return {};
- }
-
- auto kDate = hashResult.GetResult();
- hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) region string \"" << region << "\"");
- return {};
- }
-
- auto kRegion = hashResult.GetResult();
- hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\"");
- return {};
- }
-
- auto kService = hashResult.GetResult();
- hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)AWS4_REQUEST, strlen(AWS4_REQUEST)), kService);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to HMAC (SHA256) request string");
- AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << AWS4_REQUEST << "\"");
- return {};
- }
- return hashResult.GetResult();
-}
-
-AWSAuthEventStreamV4Signer::AWSAuthEventStreamV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>&
- credentialsProvider, const char* serviceName, const Aws::String& region) :
- m_serviceName(serviceName),
- m_region(region),
- m_credentialsProvider(credentialsProvider)
-{
-
- m_unsignedHeaders.emplace_back(X_AMZN_TRACE_ID);
- m_unsignedHeaders.emplace_back(USER_AGENT_HEADER);
-}
-
-bool AWSAuthEventStreamV4Signer::SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool /* signBody */) const
-{
- AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials();
-
- //don't sign anonymous requests
- if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty())
- {
- return true;
- }
-
- if (!credentials.GetSessionToken().empty())
- {
- request.SetAwsSessionToken(credentials.GetSessionToken());
- }
-
- request.SetHeaderValue(X_AMZ_CONTENT_SHA256, EVENT_STREAM_CONTENT_SHA256);
-
- //calculate date header to use in internal signature (this also goes into date header).
- DateTime now = GetSigningTimestamp();
- Aws::String dateHeaderValue = now.ToGmtString(DateFormat::ISO_8601_BASIC);
- request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue);
-
- Aws::StringStream headersStream;
- Aws::StringStream signedHeadersStream;
-
- for (const auto& header : CanonicalizeHeaders(request.GetHeaders()))
- {
- if(ShouldSignHeader(header.first))
- {
- headersStream << header.first.c_str() << ":" << header.second.c_str() << NEWLINE;
- signedHeadersStream << header.first.c_str() << ";";
- }
- }
-
- Aws::String canonicalHeadersString = headersStream.str();
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Canonical Header String: " << canonicalHeadersString);
-
- //calculate signed headers parameter
- Aws::String signedHeadersValue = signedHeadersStream.str();
- //remove that last semi-colon
- if (!signedHeadersValue.empty())
- {
- signedHeadersValue.pop_back();
- }
-
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Signed Headers value:" << signedHeadersValue);
-
- //generate generalized canonicalized request string.
- Aws::String canonicalRequestString = CanonicalizeRequestSigningString(request, true/* m_urlEscapePath */);
-
- //append v4 stuff to the canonical request string.
- canonicalRequestString.append(canonicalHeadersString);
- canonicalRequestString.append(NEWLINE);
- canonicalRequestString.append(signedHeadersValue);
- canonicalRequestString.append(NEWLINE);
- canonicalRequestString.append(EVENT_STREAM_CONTENT_SHA256);
-
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Canonical Request String: " << canonicalRequestString);
-
- //now compute sha256 on that request string
- auto hashResult = m_hash.Calculate(canonicalRequestString);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) request string");
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The request string is: \"" << canonicalRequestString << "\"");
- return false;
- }
-
- auto sha256Digest = hashResult.GetResult();
- Aws::String canonicalRequestHash = HashingUtils::HexEncode(sha256Digest);
- Aws::String simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR);
-
- Aws::String signingRegion = region ? region : m_region;
- Aws::String signingServiceName = serviceName ? serviceName : m_serviceName;
- Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName);
- auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName);
-
- Aws::StringStream ss;
- ss << AWS_HMAC_SHA256 << " " << CREDENTIAL << EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate
- << "/" << signingRegion << "/" << signingServiceName << "/" << AWS4_REQUEST << ", " << SIGNED_HEADERS << EQ
- << signedHeadersValue << ", " << SIGNATURE << EQ << HashingUtils::HexEncode(finalSignature);
-
- auto awsAuthString = ss.str();
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Signing request with: " << awsAuthString);
- request.SetAwsAuthorization(awsAuthString);
- request.SetSigningAccessKey(credentials.GetAWSAccessKeyId());
- request.SetSigningRegion(signingRegion);
- return true;
-}
-
-// this works regardless if the current machine is Big/Little Endian
-static void WriteBigEndian(Aws::String& str, uint64_t n)
-{
- int shift = 56;
- while(shift >= 0)
- {
- str.push_back((n >> shift) & 0xFF);
- shift -= 8;
- }
-}
-
-bool AWSAuthEventStreamV4Signer::SignEventMessage(Event::Message& message, Aws::String& priorSignature) const
-{
- using Event::EventHeaderValue;
-
- Aws::StringStream stringToSign;
- stringToSign << EVENT_STREAM_PAYLOAD << NEWLINE;
- const DateTime now = GetSigningTimestamp();
- const auto simpleDate = now.ToGmtString(SIMPLE_DATE_FORMAT_STR);
- stringToSign << now.ToGmtString(DateFormat::ISO_8601_BASIC) << NEWLINE
- << simpleDate << "/" << m_region << "/"
- << m_serviceName << "/aws4_request" << NEWLINE << priorSignature << NEWLINE;
-
-
- Aws::String nonSignatureHeaders;
- nonSignatureHeaders.push_back(char(sizeof(EVENTSTREAM_DATE_HEADER) - 1)); // length of the string
- nonSignatureHeaders += EVENTSTREAM_DATE_HEADER;
- nonSignatureHeaders.push_back(static_cast<char>(EventHeaderValue::EventHeaderType::TIMESTAMP)); // type of the value
- WriteBigEndian(nonSignatureHeaders, static_cast<uint64_t>(now.Millis())); // the value of the timestamp in big-endian
-
- auto hashOutcome = m_hash.Calculate(nonSignatureHeaders);
- if (!hashOutcome.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) non-signature headers.");
- return false;
- }
-
- const auto nonSignatureHeadersHash = hashOutcome.GetResult();
- stringToSign << HashingUtils::HexEncode(nonSignatureHeadersHash) << NEWLINE;
-
- if (message.GetEventPayload().empty())
- {
- AWS_LOGSTREAM_WARN(v4StreamingLogTag, "Attempting to sign an empty message (no payload and no headers). "
- "It is unlikely that this is the intended behavior.");
- }
- else
- {
- // use a preallocatedStreamBuf to avoid making a copy.
- // The Hashing API requires either Aws::String or IStream as input.
- // TODO: the hashing API should be accept 'unsigned char*' as input.
- Utils::Stream::PreallocatedStreamBuf streamBuf(message.GetEventPayload().data(), message.GetEventPayload().size());
- Aws::IOStream payload(&streamBuf);
- hashOutcome = m_hash.Calculate(payload);
-
- if (!hashOutcome.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) non-signature headers.");
- return false;
- }
- const auto payloadHash = hashOutcome.GetResult();
- stringToSign << HashingUtils::HexEncode(payloadHash);
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Payload hash - " << HashingUtils::HexEncode(payloadHash));
- }
-
- Utils::ByteBuffer finalSignatureDigest = GenerateSignature(m_credentialsProvider->GetAWSCredentials(), stringToSign.str(), simpleDate, m_region, m_serviceName);
- const auto finalSignature = HashingUtils::HexEncode(finalSignatureDigest);
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Final computed signing hash: " << finalSignature);
- priorSignature = finalSignature;
-
- message.InsertEventHeader(EVENTSTREAM_DATE_HEADER, EventHeaderValue(now.Millis(), EventHeaderValue::EventHeaderType::TIMESTAMP));
- message.InsertEventHeader(EVENTSTREAM_SIGNATURE_HEADER, std::move(finalSignatureDigest));
-
- AWS_LOGSTREAM_INFO(v4StreamingLogTag, "Event chunk final signature - " << finalSignature);
- return true;
-}
-
-bool AWSAuthEventStreamV4Signer::ShouldSignHeader(const Aws::String& header) const
-{
- return std::find(m_unsignedHeaders.cbegin(), m_unsignedHeaders.cend(), Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend();
-}
-
-Utils::ByteBuffer AWSAuthEventStreamV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign,
- const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const
-{
- Utils::Threading::ReaderLockGuard guard(m_derivedKeyLock);
- const auto& secretKey = credentials.GetAWSSecretKey();
- if (secretKey != m_currentSecretKey || simpleDate != m_currentDateStr)
- {
- guard.UpgradeToWriterLock();
- // double-checked lock to prevent updating twice
- if (m_currentDateStr != simpleDate || m_currentSecretKey != secretKey)
- {
- m_currentSecretKey = secretKey;
- m_currentDateStr = simpleDate;
- m_derivedKey = ComputeHash(m_currentSecretKey, m_currentDateStr, region, serviceName);
- }
-
- }
- return GenerateSignature(stringToSign, m_derivedKey);
-}
-
-Utils::ByteBuffer AWSAuthEventStreamV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const
-{
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Final String to sign: " << stringToSign);
-
- Aws::StringStream ss;
-
- auto hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Unable to hmac (sha256) final string");
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The final string is: \"" << stringToSign << "\"");
- return {};
- }
-
- return hashResult.GetResult();
-}
-
-Aws::String AWSAuthEventStreamV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate,
- const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const
-{
- //generate the actual string we will use in signing the final request.
- Aws::StringStream ss;
-
- ss << AWS_HMAC_SHA256 << NEWLINE << dateValue << NEWLINE << simpleDate << "/" << region << "/"
- << serviceName << "/" << AWS4_REQUEST << NEWLINE << canonicalRequestHash;
-
- return ss.str();
-}
-
-Aws::Utils::ByteBuffer AWSAuthEventStreamV4Signer::ComputeHash(const Aws::String& secretKey,
- const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const
-{
- Aws::String signingKey(SIGNING_KEY);
- signingKey.append(secretKey);
- auto hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()),
- ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length()));
-
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\"");
- return {};
- }
-
- auto kDate = hashResult.GetResult();
- hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) region string \"" << region << "\"");
- return {};
- }
-
- auto kRegion = hashResult.GetResult();
- hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\"");
- return {};
- }
-
- auto kService = hashResult.GetResult();
- hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)AWS4_REQUEST, strlen(AWS4_REQUEST)), kService);
- if (!hashResult.IsSuccess())
- {
- AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Unable to HMAC (SHA256) request string");
- AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The request string is: \"" << AWS4_REQUEST << "\"");
- return {};
- }
- return hashResult.GetResult();
-}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp
index bf20ede35e..084e4bca6e 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProvider.cpp
@@ -48,7 +48,7 @@ static const char DEFAULT_CREDENTIALS_FILE[] = "credentials";
extern const char DEFAULT_CONFIG_FILE[] = "config";
-static const int EXPIRATION_GRACE_PERIOD = 5 * 1000;
+static const int AWS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD = 5 * 1000;
void AWSCredentialsProvider::Reload()
{
@@ -183,9 +183,10 @@ AWSCredentials ProfileConfigFileAWSCredentialsProvider::GetAWSCredentials()
{
RefreshIfExpired();
ReaderLockGuard guard(m_reloadLock);
- auto credsFileProfileIter = m_credentialsFileLoader.GetProfiles().find(m_profileToUse);
+ const Aws::Map<Aws::String, Aws::Config::Profile>& profiles = m_credentialsFileLoader.GetProfiles();
+ auto credsFileProfileIter = profiles.find(m_profileToUse);
- if(credsFileProfileIter != m_credentialsFileLoader.GetProfiles().end())
+ if(credsFileProfileIter != profiles.end())
{
return credsFileProfileIter->second.GetCredentials();
}
@@ -239,37 +240,71 @@ AWSCredentials InstanceProfileCredentialsProvider::GetAWSCredentials()
{
RefreshIfExpired();
ReaderLockGuard guard(m_reloadLock);
+ if (m_ec2MetadataConfigLoader)
+ {
+ const Aws::Map<Aws::String, Aws::Config::Profile> &profiles = m_ec2MetadataConfigLoader->GetProfiles();
+ auto profileIter = profiles.find(Aws::Config::INSTANCE_PROFILE_KEY);
+
+ if (profileIter != profiles.end()) {
+ return profileIter->second.GetCredentials();
+ }
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(INSTANCE_LOG_TAG, "EC2 Metadata config loader is a nullptr");
+ }
+
+ return AWSCredentials();
+}
+
+bool InstanceProfileCredentialsProvider::ExpiresSoon() const
+{
+ ReaderLockGuard guard(m_reloadLock);
auto profileIter = m_ec2MetadataConfigLoader->GetProfiles().find(Aws::Config::INSTANCE_PROFILE_KEY);
+ AWSCredentials credentials;
if(profileIter != m_ec2MetadataConfigLoader->GetProfiles().end())
{
- return profileIter->second.GetCredentials();
+ credentials = profileIter->second.GetCredentials();
}
- return AWSCredentials();
+ return ((credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < AWS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD);
}
void InstanceProfileCredentialsProvider::Reload()
{
- AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Credentials have expired attempting to repull from EC2 Metadata Service.");
- m_ec2MetadataConfigLoader->Load();
- AWSCredentialsProvider::Reload();
+ AWS_LOGSTREAM_INFO(INSTANCE_LOG_TAG, "Credentials have expired attempting to re-pull from EC2 Metadata Service.");
+ if (m_ec2MetadataConfigLoader) {
+ m_ec2MetadataConfigLoader->Load();
+ AWSCredentialsProvider::Reload();
+ } else {
+ AWS_LOGSTREAM_ERROR(INSTANCE_LOG_TAG, "EC2 Metadata config loader is a nullptr");
+ }
}
void InstanceProfileCredentialsProvider::RefreshIfExpired()
{
AWS_LOGSTREAM_DEBUG(INSTANCE_LOG_TAG, "Checking if latest credential pull has expired.");
ReaderLockGuard guard(m_reloadLock);
- if (!IsTimeToRefresh(m_loadFrequencyMs))
- {
- return;
- }
+ auto profileIter = m_ec2MetadataConfigLoader->GetProfiles().find(Aws::Config::INSTANCE_PROFILE_KEY);
+ AWSCredentials credentials;
- guard.UpgradeToWriterLock();
- if (!IsTimeToRefresh(m_loadFrequencyMs)) // double-checked lock to avoid refreshing twice
+ if(profileIter != m_ec2MetadataConfigLoader->GetProfiles().end())
{
- return;
+ credentials = profileIter->second.GetCredentials();
+
+ if (!credentials.IsEmpty() && !IsTimeToRefresh(m_loadFrequencyMs) && !ExpiresSoon())
+ {
+ return;
+ }
+
+ guard.UpgradeToWriterLock();
+ if (!credentials.IsEmpty() && !IsTimeToRefresh(m_loadFrequencyMs) && !ExpiresSoon()) // double-checked lock to avoid refreshing twice
+ {
+ return;
+ }
}
+
Reload();
}
@@ -306,12 +341,17 @@ AWSCredentials TaskRoleCredentialsProvider::GetAWSCredentials()
bool TaskRoleCredentialsProvider::ExpiresSoon() const
{
- return ((m_credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < EXPIRATION_GRACE_PERIOD);
+ return ((m_credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < AWS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD);
}
void TaskRoleCredentialsProvider::Reload()
{
- AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Credentials have expired or will expire, attempting to repull from ECS IAM Service.");
+ AWS_LOGSTREAM_INFO(TASK_ROLE_LOG_TAG, "Credentials have expired or will expire, attempting to re-pull from ECS IAM Service.");
+ if (!m_ecsCredentialsClient)
+ {
+ AWS_LOGSTREAM_ERROR(INSTANCE_LOG_TAG, "ECS Credentials client is a nullptr");
+ return;
+ }
auto credentialsStr = m_ecsCredentialsClient->GetECSCredentials();
if (credentialsStr.empty()) return;
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp
index 8b019a1664..403bd380c4 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp
@@ -77,3 +77,9 @@ DefaultAWSCredentialsProviderChain::DefaultAWSCredentialsProviderChain() : AWSCr
AWS_LOGSTREAM_INFO(DefaultCredentialsProviderChainTag, "Added EC2 metadata service credentials provider to the provider chain.");
}
}
+
+DefaultAWSCredentialsProviderChain::DefaultAWSCredentialsProviderChain(const DefaultAWSCredentialsProviderChain& chain) {
+ for (const auto& provider: chain.GetProviders()) {
+ AddProvider(provider);
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp
index e8f780762e..9576e9d999 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/SSOCredentialsProvider.cpp
@@ -33,7 +33,8 @@ SSOCredentialsProvider::SSOCredentialsProvider() : m_profileToUse(GetConfigProfi
AWS_LOGSTREAM_INFO(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Setting sso credentials provider to read config from " << m_profileToUse);
}
-SSOCredentialsProvider::SSOCredentialsProvider(const Aws::String& profile) : m_profileToUse(profile)
+SSOCredentialsProvider::SSOCredentialsProvider(const Aws::String& profile) : m_profileToUse(profile),
+ m_bearerTokenProvider(profile)
{
AWS_LOGSTREAM_INFO(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Setting sso credentials provider to read config from " << m_profileToUse);
}
@@ -48,15 +49,24 @@ AWSCredentials SSOCredentialsProvider::GetAWSCredentials()
void SSOCredentialsProvider::Reload()
{
auto profile = Aws::Config::GetCachedConfigProfile(m_profileToUse);
-
- Aws::String hashedStartUrl = Aws::Utils::HashingUtils::HexEncode(Aws::Utils::HashingUtils::CalculateSHA1(profile.GetSsoStartUrl()));
- auto profileDirectory = ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory();
- Aws::StringStream ssToken;
- ssToken << profileDirectory;
- ssToken << PATH_DELIM << "sso" << PATH_DELIM << "cache" << PATH_DELIM << hashedStartUrl << ".json";
- auto ssoTokenPath = ssToken.str();
- AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Loading token from: " << ssoTokenPath)
- Aws::String accessToken = LoadAccessTokenFile(ssoTokenPath);
+ const auto accessToken = [&]() -> Aws::String {
+ // If we have an SSO Session set, use the refreshed token.
+ if (profile.IsSsoSessionSet()) {
+ m_ssoRegion = profile.GetSsoSession().GetSsoRegion();
+ auto token = m_bearerTokenProvider.GetAWSBearerToken();
+ m_expiresAt = token.GetExpiration();
+ return token.GetToken();
+ }
+ Aws::String hashedStartUrl = Aws::Utils::HashingUtils::HexEncode(Aws::Utils::HashingUtils::CalculateSHA1(profile.GetSsoStartUrl()));
+ auto profileDirectory = ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory();
+ Aws::StringStream ssToken;
+ ssToken << profileDirectory;
+ ssToken << PATH_DELIM << "sso" << PATH_DELIM << "cache" << PATH_DELIM << hashedStartUrl << ".json";
+ auto ssoTokenPath = ssToken.str();
+ AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Loading token from: " << ssoTokenPath)
+ m_ssoRegion = profile.GetSsoRegion();
+ return LoadAccessTokenFile(ssoTokenPath);
+ }();
if (accessToken.empty()) {
AWS_LOGSTREAM_TRACE(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Access token for SSO not available");
return;
@@ -72,7 +82,7 @@ void SSOCredentialsProvider::Reload()
Aws::Client::ClientConfiguration config;
config.scheme = Aws::Http::Scheme::HTTPS;
- config.region = profile.GetSsoRegion();
+ config.region = m_ssoRegion;
AWS_LOGSTREAM_DEBUG(SSO_CREDENTIALS_PROVIDER_LOG_TAG, "Passing config to client for region: " << m_ssoRegion);
Aws::Vector<Aws::String> retryableErrors;
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp
index 3f48c9e0c7..b861e6132b 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/STSCredentialsProvider.cpp
@@ -30,6 +30,8 @@ using Aws::Utils::Threading::ReaderLockGuard;
using Aws::Utils::Threading::WriterLockGuard;
static const char STS_ASSUME_ROLE_WEB_IDENTITY_LOG_TAG[] = "STSAssumeRoleWithWebIdentityCredentialsProvider";
+static const int STS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD = 5 * 1000;
+
STSAssumeRoleWebIdentityCredentialsProvider::STSAssumeRoleWebIdentityCredentialsProvider() :
m_initialized(false)
{
@@ -145,16 +147,21 @@ void STSAssumeRoleWebIdentityCredentialsProvider::Reload()
m_credentials = result.creds;
}
+bool STSAssumeRoleWebIdentityCredentialsProvider::ExpiresSoon() const
+{
+ return ((m_credentials.GetExpiration() - Aws::Utils::DateTime::Now()).count() < STS_CREDENTIAL_PROVIDER_EXPIRATION_GRACE_PERIOD);
+}
+
void STSAssumeRoleWebIdentityCredentialsProvider::RefreshIfExpired()
{
ReaderLockGuard guard(m_reloadLock);
- if (!m_credentials.IsExpiredOrEmpty())
+ if (!m_credentials.IsEmpty() && !ExpiresSoon())
{
return;
}
guard.UpgradeToWriterLock();
- if (!m_credentials.IsExpiredOrEmpty()) // double-checked lock to avoid refreshing twice
+ if (!m_credentials.IsExpiredOrEmpty() && !ExpiresSoon()) // double-checked lock to avoid refreshing twice
{
return;
}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp
new file mode 100644
index 0000000000..16b301cd67
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/DefaultBearerTokenProviderChain.cpp
@@ -0,0 +1,35 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/auth/bearer-token-provider/DefaultBearerTokenProviderChain.h>
+#include <aws/core/auth/AWSBearerToken.h>
+#include <aws/core/auth/bearer-token-provider/SSOBearerTokenProvider.h>
+#include <aws/core/utils/logging/LogMacros.h>
+
+
+static const char SSO_DEFAULT_BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG[] = "SSOBearerTokenProvider";
+
+Aws::Auth::AWSBearerToken Aws::Auth::DefaultBearerTokenProviderChain::GetAWSBearerToken()
+{
+ for (auto&& bearerTokenProvider : m_providerChain)
+ {
+ if(!bearerTokenProvider) {
+ AWS_LOGSTREAM_FATAL(SSO_DEFAULT_BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG,
+ "Unexpected nullptr in DefaultBearerTokenProviderChain::m_providerChain");
+ break;
+ }
+ AWSBearerToken bearerToken = bearerTokenProvider->GetAWSBearerToken();
+ if(!bearerToken.IsExpiredOrEmpty())
+ {
+ return bearerToken;
+ }
+ }
+ return AWSBearerToken("", Aws::Utils::DateTime(0.0));
+}
+
+Aws::Auth::DefaultBearerTokenProviderChain::DefaultBearerTokenProviderChain()
+{
+ AddProvider(Aws::MakeShared<Aws::Auth::SSOBearerTokenProvider>(SSO_DEFAULT_BEARER_TOKEN_PROVIDER_CHAIN_LOG_TAG));
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp
new file mode 100644
index 0000000000..b55131e340
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/bearer-token-provider/SSOBearerTokenProvider.cpp
@@ -0,0 +1,244 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/auth/bearer-token-provider/SSOBearerTokenProvider.h>
+#include <aws/core/auth/AWSCredentialsProvider.h>
+#include <aws/core/config/AWSProfileConfigLoader.h>
+#include <aws/core/internal/AWSHttpResourceClient.h>
+#include <aws/core/platform/Environment.h>
+#include <aws/core/platform/FileSystem.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/utils/FileSystemUtils.h>
+#include <aws/core/client/SpecifiedRetryableErrorsRetryStrategy.h>
+#include <aws/core/utils/HashingUtils.h>
+#include <aws/core/utils/json/JsonSerializer.h>
+
+using namespace Aws::Auth;
+
+using Aws::Utils::Threading::ReaderLockGuard;
+
+
+static const char SSO_BEARER_TOKEN_PROVIDER_LOG_TAG[] = "SSOBearerTokenProvider";
+static const char SSO_GRANT_TYPE[] = "refresh_token";
+
+const size_t SSOBearerTokenProvider::REFRESH_WINDOW_BEFORE_EXPIRATION_S = 600;
+const size_t SSOBearerTokenProvider::REFRESH_ATTEMPT_INTERVAL_S = 30;
+
+SSOBearerTokenProvider::SSOBearerTokenProvider()
+ : m_profileToUse(Aws::Auth::GetConfigProfileName()),
+ m_lastUpdateAttempt((int64_t) 0)
+{
+ AWS_LOGSTREAM_INFO(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Setting sso bearerToken provider to read config from " << m_profileToUse);
+}
+
+SSOBearerTokenProvider::SSOBearerTokenProvider(const Aws::String& awsProfile)
+ : m_profileToUse(awsProfile),
+ m_lastUpdateAttempt((int64_t) 0)
+{
+ AWS_LOGSTREAM_INFO(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Setting sso bearerToken provider to read config from " << m_profileToUse);
+}
+
+AWSBearerToken SSOBearerTokenProvider::GetAWSBearerToken()
+{
+ Aws::Utils::Threading::ReaderLockGuard guard(m_reloadLock);
+ if(m_token.IsEmpty())
+ {
+ Reload();
+ }
+ if(!m_token.IsEmpty())
+ {
+ const Aws::Utils::DateTime now = Aws::Utils::DateTime::Now();
+ if (now >= m_token.GetExpiration() - std::chrono::seconds(REFRESH_WINDOW_BEFORE_EXPIRATION_S) &&
+ m_lastUpdateAttempt + std::chrono::seconds(REFRESH_ATTEMPT_INTERVAL_S) < now)
+ {
+ guard.UpgradeToWriterLock();
+ RefreshFromSso();
+ }
+ }
+
+ if(m_token.IsExpiredOrEmpty())
+ {
+ /* If a loaded token has expired and has insufficient metadata to perform a refresh the SSO token
+ provider must raise an exception that the token has expired and cannot be refreshed.
+ Error logging and returning an empty object instead because of disabled exceptions and poor legacy API design. */
+ AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "SSOBearerTokenProvider is unable to provide a token");
+ return Aws::Auth::AWSBearerToken("", Aws::Utils::DateTime(0.0));
+ }
+ return m_token;
+}
+
+void SSOBearerTokenProvider::Reload()
+{
+ CachedSsoToken cachedSsoToken = LoadAccessTokenFile();
+ if(cachedSsoToken.accessToken.empty()) {
+ AWS_LOGSTREAM_TRACE(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Access token for SSO not available");
+ return;
+ }
+ const Aws::Utils::DateTime now = Aws::Utils::DateTime::Now();
+ if(cachedSsoToken.expiresAt < now) {
+ AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Cached Token is already expired at " << cachedSsoToken.expiresAt.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
+ return;
+ }
+
+ m_token.SetToken(cachedSsoToken.accessToken);
+ m_token.SetExpiration(cachedSsoToken.expiresAt);
+}
+
+void SSOBearerTokenProvider::RefreshFromSso()
+{
+ CachedSsoToken cachedSsoToken = LoadAccessTokenFile();
+
+ if(!m_client)
+ {
+ Aws::Client::ClientConfiguration config;
+ config.scheme = Aws::Http::Scheme::HTTPS;
+ /* The SSO token provider must not resolve if any SSO configuration values are present directly on the profile
+ * instead of an `sso-session` section. The SSO token provider must ignore these configuration values if these
+ * values are present directly on the profile instead of an `sso-session` section. */
+ // config.region = m_profile.GetSsoRegion(); // <- intentionally not used per comment above
+ config.region = cachedSsoToken.region;
+ m_client = Aws::MakeUnique<Aws::Internal::SSOCredentialsClient>(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, config);
+ }
+
+ Aws::Internal::SSOCredentialsClient::SSOCreateTokenRequest ssoCreateTokenRequest;
+ ssoCreateTokenRequest.clientId = cachedSsoToken.clientId;
+ ssoCreateTokenRequest.clientSecret = cachedSsoToken.clientSecret;
+ ssoCreateTokenRequest.grantType = SSO_GRANT_TYPE;
+ ssoCreateTokenRequest.refreshToken = cachedSsoToken.refreshToken;
+
+ if(!m_client) {
+ AWS_LOGSTREAM_FATAL(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Unexpected nullptr in SSOBearerTokenProvider::m_client");
+ return;
+ }
+ Aws::Internal::SSOCredentialsClient::SSOCreateTokenResult result = m_client->CreateToken(ssoCreateTokenRequest);
+ if(!result.accessToken.empty())
+ {
+ cachedSsoToken.accessToken = result.accessToken;
+ cachedSsoToken.expiresAt = Aws::Utils::DateTime::Now() + std::chrono::seconds(result.expiresIn);
+ if(!result.refreshToken.empty()) {
+ cachedSsoToken.refreshToken = result.refreshToken;
+ }
+ if(!result.clientId.empty()) {
+ cachedSsoToken.clientId = result.clientId;
+ }
+ }
+
+ if(WriteAccessTokenFile(cachedSsoToken))
+ {
+ m_token.SetToken(cachedSsoToken.accessToken);
+ m_token.SetExpiration(cachedSsoToken.expiresAt);
+ }
+
+}
+
+SSOBearerTokenProvider::CachedSsoToken SSOBearerTokenProvider::LoadAccessTokenFile() const
+{
+ SSOBearerTokenProvider::CachedSsoToken retValue;
+
+ const Aws::Config::Profile& profile = Aws::Config::GetCachedConfigProfile(m_profileToUse);
+ if(!profile.IsSsoSessionSet()) {
+ AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "SSOBearerTokenProvider set to use a profile " << m_profileToUse << " without a sso_session. Unable to load cached token.");
+ return retValue;
+ }
+
+ Aws::String hashedStartUrl = Aws::Utils::HashingUtils::HexEncode(Aws::Utils::HashingUtils::CalculateSHA1(profile.GetSsoSession().GetName()));
+ Aws::String profileDirectory = ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory();
+ Aws::StringStream ssToken;
+ ssToken << profileDirectory;
+ ssToken << Aws::FileSystem::PATH_DELIM << "sso" << Aws::FileSystem::PATH_DELIM << "cache" << Aws::FileSystem::PATH_DELIM << hashedStartUrl << ".json";
+ auto ssoAccessTokenPath = ssToken.str();
+ AWS_LOGSTREAM_DEBUG(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Preparing to load token from: " << ssoAccessTokenPath);
+
+ Aws::IFStream inputFile(ssoAccessTokenPath.c_str());
+ if(inputFile)
+ {
+ AWS_LOGSTREAM_DEBUG(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Reading content from token file: " << ssoAccessTokenPath);
+
+ Aws::Utils::Json::JsonValue tokenDoc(inputFile);
+ if (!tokenDoc.WasParseSuccessful())
+ {
+ AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Failed to parse token file: " << ssoAccessTokenPath);
+ return retValue;
+ }
+ Utils::Json::JsonView tokenView(tokenDoc);
+
+ retValue.accessToken = tokenView.GetString("accessToken");
+ retValue.expiresAt = Aws::Utils::DateTime(tokenView.GetString("expiresAt"), Aws::Utils::DateFormat::ISO_8601);
+ retValue.refreshToken = tokenView.GetString("refreshToken");
+ retValue.clientId = tokenView.GetString("clientId");
+ retValue.clientSecret = tokenView.GetString("clientSecret");
+ retValue.registrationExpiresAt = Aws::Utils::DateTime(tokenView.GetString("registrationExpiresAt"), Aws::Utils::DateFormat::ISO_8601);
+ retValue.region = tokenView.GetString("region");
+ retValue.startUrl = tokenView.GetString("startUrl");
+
+ return retValue;
+ }
+ else
+ {
+ AWS_LOGSTREAM_INFO(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Unable to open token file on path: " << ssoAccessTokenPath);
+ return retValue;
+ }
+}
+
+bool SSOBearerTokenProvider::WriteAccessTokenFile(const CachedSsoToken& token) const
+{
+ const Aws::Config::Profile& profile = Aws::Config::GetCachedConfigProfile(m_profileToUse);
+ if(!profile.IsSsoSessionSet()) {
+ AWS_LOGSTREAM_ERROR(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "SSOBearerTokenProvider set to use a profile "
+ << m_profileToUse << " without a sso_session. Unable to write a cached token.");
+ return false;
+ }
+
+ Aws::String hashedStartUrl = Aws::Utils::HashingUtils::HexEncode(Aws::Utils::HashingUtils::CalculateSHA1(profile.GetSsoSession().GetName()));
+ Aws::String profileDirectory = ProfileConfigFileAWSCredentialsProvider::GetProfileDirectory();
+ Aws::StringStream ssToken;
+ ssToken << profileDirectory;
+ ssToken << Aws::FileSystem::PATH_DELIM << "sso" << Aws::FileSystem::PATH_DELIM << "cache" << Aws::FileSystem::PATH_DELIM << hashedStartUrl << ".json";
+ auto ssoAccessTokenPath = ssToken.str();
+ AWS_LOGSTREAM_DEBUG(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Preparing to write token to: " << ssoAccessTokenPath);
+
+ Aws::OFStream outputFileStream(ssoAccessTokenPath.c_str(), std::ios_base::out | std::ios_base::trunc);
+ if(outputFileStream && outputFileStream.good())
+ {
+ AWS_LOGSTREAM_DEBUG(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Writing content to token file: " << ssoAccessTokenPath);
+
+ Aws::Utils::Json::JsonValue cachedTokenDoc;
+ if(!token.accessToken.empty()) {
+ cachedTokenDoc.WithString("accessToken", token.accessToken);
+ }
+ if(token.expiresAt != 0.0) {
+ cachedTokenDoc.WithString("expiresAt", token.expiresAt.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
+ }
+ if(!token.refreshToken.empty()) {
+ cachedTokenDoc.WithString("refreshToken", token.refreshToken);
+ }
+ if(!token.clientId.empty()) {
+ cachedTokenDoc.WithString("clientId", token.clientId);
+ }
+ if(!token.clientSecret.empty()) {
+ cachedTokenDoc.WithString("clientSecret", token.clientSecret);
+ }
+ if(token.registrationExpiresAt != 0.0) {
+ cachedTokenDoc.WithString("registrationExpiresAt", token.registrationExpiresAt.ToGmtString(Aws::Utils::DateFormat::ISO_8601));
+ }
+ if(!token.region.empty()) {
+ cachedTokenDoc.WithString("region", token.region);
+ }
+ if(!token.startUrl.empty()) {
+ cachedTokenDoc.WithString("startUrl", token.startUrl);
+ }
+
+ const Aws::String& resultingJsonStr = cachedTokenDoc.View().WriteReadable();;
+ outputFileStream << resultingJsonStr;
+
+ return outputFileStream.good();
+ }
+ else
+ {
+ AWS_LOGSTREAM_INFO(SSO_BEARER_TOKEN_PROVIDER_LOG_TAG, "Unable to open token file on path for writing: " << ssoAccessTokenPath);
+ return false;
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp
new file mode 100644
index 0000000000..9bb9c5edae
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/BearerTokenAuthSignerProvider.cpp
@@ -0,0 +1,46 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/auth/signer-provider/BearerTokenAuthSignerProvider.h>
+
+#include <aws/core/auth/signer/AWSNullSigner.h>
+
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/auth/AWSCredentialsProvider.h>
+#include <aws/core/utils/memory/stl/AWSAllocator.h>
+
+const char BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG[] = "BearerTokenAuthSignerProvider";
+
+using namespace Aws::Auth;
+
+BearerTokenAuthSignerProvider::BearerTokenAuthSignerProvider(const std::shared_ptr<Aws::Auth::AWSBearerTokenProviderBase> bearerTokenProvider)
+{
+ m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthBearerSigner>(BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG, bearerTokenProvider));
+ m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSNullSigner>(BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG));
+}
+
+std::shared_ptr<Aws::Client::AWSAuthSigner> BearerTokenAuthSignerProvider::GetSigner(const Aws::String& signerName) const
+{
+ for(const auto& signer : m_signers)
+ {
+ if(!signer) {
+ AWS_LOGSTREAM_FATAL(BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG, "Unexpected nullptr in BearerTokenAuthSignerProvider::m_signers");
+ break;
+ }
+ if(signer->GetName() == signerName)
+ {
+ return signer;
+ }
+ }
+ AWS_LOGSTREAM_ERROR(BEARER_TOKEN_AUTH_SIGNER_PROVIDER_ALLOC_TAG, "Request's signer: '" << signerName << "' is not found in the signer's map.");
+ assert(false);
+ return nullptr;
+}
+
+void BearerTokenAuthSignerProvider::AddSigner(std::shared_ptr<Aws::Client::AWSAuthSigner>& signer)
+{
+ assert(signer);
+ m_signers.emplace_back(signer);
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp
index 31fd6c006b..fb7e0cfa40 100644
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/AWSAuthSignerProvider.cpp
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer-provider/DefaultAuthSignerProvider.cpp
@@ -2,10 +2,14 @@
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
+
+#include <aws/core/auth/signer-provider/DefaultAuthSignerProvider.h>
+
+#include <aws/core/auth/signer/AWSAuthEventStreamV4Signer.h>
+#include <aws/core/auth/signer/AWSNullSigner.h>
+
#include <aws/core/utils/logging/LogMacros.h>
-#include <aws/core/auth/AWSAuthSignerProvider.h>
-#include <aws/core/auth/AWSAuthSigner.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/core/utils/memory/stl/AWSAllocator.h>
@@ -14,9 +18,10 @@ const char CLASS_TAG[] = "AuthSignerProvider";
using namespace Aws::Auth;
DefaultAuthSignerProvider::DefaultAuthSignerProvider(const std::shared_ptr<AWSCredentialsProvider>& credentialsProvider,
- const Aws::String& serviceName, const Aws::String& region)
+ const Aws::String& serviceName, const Aws::String& region, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy signingPolicy, bool urlEscapePath)
{
- m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthV4Signer>(CLASS_TAG, credentialsProvider, serviceName.c_str(), region));
+ m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthV4Signer>(CLASS_TAG, credentialsProvider, serviceName.c_str(), region, signingPolicy, urlEscapePath, AWSSigningAlgorithm::SIGV4));
+ m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthV4Signer>(CLASS_TAG, credentialsProvider, serviceName.c_str(), region, signingPolicy, urlEscapePath, AWSSigningAlgorithm::ASYMMETRIC_SIGV4));
m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSAuthEventStreamV4Signer>(CLASS_TAG, credentialsProvider, serviceName.c_str(), region));
m_signers.emplace_back(Aws::MakeShared<Aws::Client::AWSNullSigner>(CLASS_TAG));
}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp
new file mode 100644
index 0000000000..ff14c8a371
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthBearerSigner.cpp
@@ -0,0 +1,50 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/auth/signer/AWSAuthBearerSigner.h>
+#include <aws/core/auth/bearer-token-provider/AWSBearerTokenProviderBase.h>
+
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/http/HttpRequest.h>
+
+namespace Aws
+{
+ namespace Auth
+ {
+ const char BEARER_SIGNER[] = "Bearer";
+ }
+
+ namespace Client
+ {
+ static const char LOGGING_TAG[] = "AWSAuthBearerSigner";
+ static const char AUTHORIZATION_HEADER[] = "authorization";
+
+ bool AWSAuthBearerSigner::SignRequest(Aws::Http::HttpRequest& ioRequest) const
+ {
+ if(Aws::Http::Scheme::HTTPS != ioRequest.GetUri().GetScheme())
+ {
+ // Clients MUST always use TLS (https) or equivalent transport security
+ // when making requests with bearer tokens.
+ // https://datatracker.ietf.org/doc/html/rfc6750
+ AWS_LOGSTREAM_ERROR(LOGGING_TAG, "HTTPS scheme must be used with a bearer token authorization");
+ return false;
+ }
+ if(!m_bearerTokenProvider)
+ {
+ AWS_LOGSTREAM_FATAL(LOGGING_TAG, "Unexpected nullptr AWSAuthBearerSigner::m_bearerTokenProvider");
+ return false;
+ }
+ const Aws::Auth::AWSBearerToken& token = m_bearerTokenProvider->GetAWSBearerToken();
+ if(token.IsExpiredOrEmpty())
+ {
+ AWS_LOGSTREAM_ERROR(LOGGING_TAG, "Invalid bearer token to use: expired or empty");
+ return false;
+ }
+
+ ioRequest.SetHeaderValue(AUTHORIZATION_HEADER, "Bearer " + token.GetToken());
+ return true;
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp
new file mode 100644
index 0000000000..195e83a751
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthEventStreamV4Signer.cpp
@@ -0,0 +1,320 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/auth/signer/AWSAuthEventStreamV4Signer.h>
+#include <aws/core/auth/signer/AWSAuthSignerCommon.h>
+#include <aws/core/auth/signer/AWSAuthSignerHelper.h>
+
+#include <aws/core/auth/AWSCredentialsProvider.h>
+#include <aws/core/http/HttpRequest.h>
+#include <aws/core/utils/DateTime.h>
+#include <aws/core/utils/HashingUtils.h>
+#include <aws/core/utils/Outcome.h>
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/utils/memory/AWSMemory.h>
+#include <aws/core/utils/crypto/Sha256HMAC.h>
+#include <aws/core/utils/stream/PreallocatedStreamBuf.h>
+#include <aws/core/utils/event/EventMessage.h>
+#include <aws/core/utils/event/EventHeader.h>
+
+#include <aws/crt/auth/Credentials.h>
+#include <aws/crt/http/HttpRequestResponse.h>
+
+#include <iomanip>
+#include <cstring>
+
+using namespace Aws;
+using namespace Aws::Client;
+using namespace Aws::Auth;
+using namespace Aws::Http;
+using namespace Aws::Utils;
+using namespace Aws::Utils::Logging;
+
+static const char* EVENT_STREAM_CONTENT_SHA256 = "STREAMING-AWS4-HMAC-SHA256-EVENTS";
+static const char* EVENT_STREAM_PAYLOAD = "AWS4-HMAC-SHA256-PAYLOAD";
+static const char* v4StreamingLogTag = "AWSAuthEventStreamV4Signer";
+
+namespace Aws
+{
+ namespace Auth
+ {
+ const char EVENTSTREAM_SIGV4_SIGNER[] = "EventStreamSignatureV4";
+ const char EVENTSTREAM_SIGNATURE_HEADER[] = ":chunk-signature";
+ const char EVENTSTREAM_DATE_HEADER[] = ":date";
+ }
+}
+
+AWSAuthEventStreamV4Signer::AWSAuthEventStreamV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>&
+ credentialsProvider, const char* serviceName, const Aws::String& region) :
+ m_serviceName(serviceName),
+ m_region(region),
+ m_credentialsProvider(credentialsProvider)
+{
+
+ m_unsignedHeaders.emplace_back(Aws::Auth::AWSAuthHelper::X_AMZN_TRACE_ID);
+ m_unsignedHeaders.emplace_back(USER_AGENT_HEADER);
+}
+
+bool AWSAuthEventStreamV4Signer::SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool /* signBody */) const
+{
+ AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials();
+
+ //don't sign anonymous requests
+ if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty())
+ {
+ return true;
+ }
+
+ if (!credentials.GetSessionToken().empty())
+ {
+ request.SetAwsSessionToken(credentials.GetSessionToken());
+ }
+
+ request.SetHeaderValue(Aws::Auth::AWSAuthHelper::X_AMZ_CONTENT_SHA256, EVENT_STREAM_CONTENT_SHA256);
+
+ //calculate date header to use in internal signature (this also goes into date header).
+ DateTime now = GetSigningTimestamp();
+ Aws::String dateHeaderValue = now.ToGmtString(DateFormat::ISO_8601_BASIC);
+ request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue);
+
+ Aws::StringStream headersStream;
+ Aws::StringStream signedHeadersStream;
+
+ for (const auto& header : Aws::Auth::AWSAuthHelper::CanonicalizeHeaders(request.GetHeaders()))
+ {
+ if(ShouldSignHeader(header.first))
+ {
+ headersStream << header.first.c_str() << ":" << header.second.c_str() << Aws::Auth::AWSAuthHelper::NEWLINE;
+ signedHeadersStream << header.first.c_str() << ";";
+ }
+ }
+
+ Aws::String canonicalHeadersString = headersStream.str();
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Canonical Header String: " << canonicalHeadersString);
+
+ //calculate signed headers parameter
+ Aws::String signedHeadersValue = signedHeadersStream.str();
+ //remove that last semi-colon
+ if (!signedHeadersValue.empty())
+ {
+ signedHeadersValue.pop_back();
+ }
+
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Signed Headers value:" << signedHeadersValue);
+
+ //generate generalized canonicalized request string.
+ Aws::String canonicalRequestString = Aws::Auth::AWSAuthHelper::CanonicalizeRequestSigningString(request, true/* m_urlEscapePath */);
+
+ //append v4 stuff to the canonical request string.
+ canonicalRequestString.append(canonicalHeadersString);
+ canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE);
+ canonicalRequestString.append(signedHeadersValue);
+ canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE);
+ canonicalRequestString.append(EVENT_STREAM_CONTENT_SHA256);
+
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Canonical Request String: " << canonicalRequestString);
+
+ //now compute sha256 on that request string
+ auto hashResult = m_hash.Calculate(canonicalRequestString);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) request string");
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The request string is: \"" << canonicalRequestString << "\"");
+ return false;
+ }
+
+ auto sha256Digest = hashResult.GetResult();
+ Aws::String canonicalRequestHash = HashingUtils::HexEncode(sha256Digest);
+ Aws::String simpleDate = now.ToGmtString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR);
+
+ Aws::String signingRegion = region ? region : m_region;
+ Aws::String signingServiceName = serviceName ? serviceName : m_serviceName;
+ Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName);
+ auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName);
+
+ Aws::StringStream ss;
+ ss << Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256 << " " << Aws::Auth::AWSAuthHelper::CREDENTIAL << Aws::Auth::AWSAuthHelper::EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate
+ << "/" << signingRegion << "/" << signingServiceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << ", " << Aws::Auth::AWSAuthHelper::SIGNED_HEADERS << Aws::Auth::AWSAuthHelper::EQ
+ << signedHeadersValue << ", " << SIGNATURE << Aws::Auth::AWSAuthHelper::EQ << HashingUtils::HexEncode(finalSignature);
+
+ auto awsAuthString = ss.str();
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Signing request with: " << awsAuthString);
+ request.SetAwsAuthorization(awsAuthString);
+ request.SetSigningAccessKey(credentials.GetAWSAccessKeyId());
+ request.SetSigningRegion(signingRegion);
+ return true;
+}
+
+// this works regardless if the current machine is Big/Little Endian
+static void WriteBigEndian(Aws::String& str, uint64_t n)
+{
+ int shift = 56;
+ while(shift >= 0)
+ {
+ str.push_back((n >> shift) & 0xFF);
+ shift -= 8;
+ }
+}
+
+bool AWSAuthEventStreamV4Signer::SignEventMessage(Event::Message& message, Aws::String& priorSignature) const
+{
+ using Event::EventHeaderValue;
+
+ Aws::StringStream stringToSign;
+ stringToSign << EVENT_STREAM_PAYLOAD << Aws::Auth::AWSAuthHelper::NEWLINE;
+ const DateTime now = GetSigningTimestamp();
+ const auto simpleDate = now.ToGmtString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR);
+ stringToSign << now.ToGmtString(DateFormat::ISO_8601_BASIC) << Aws::Auth::AWSAuthHelper::NEWLINE
+ << simpleDate << "/" << m_region << "/"
+ << m_serviceName << "/aws4_request" << Aws::Auth::AWSAuthHelper::NEWLINE << priorSignature << Aws::Auth::AWSAuthHelper::NEWLINE;
+
+
+ Aws::String nonSignatureHeaders;
+ nonSignatureHeaders.push_back(char(sizeof(EVENTSTREAM_DATE_HEADER) - 1)); // length of the string
+ nonSignatureHeaders += EVENTSTREAM_DATE_HEADER;
+ nonSignatureHeaders.push_back(static_cast<char>(EventHeaderValue::EventHeaderType::TIMESTAMP)); // type of the value
+ WriteBigEndian(nonSignatureHeaders, static_cast<uint64_t>(now.Millis())); // the value of the timestamp in big-endian
+
+ auto hashOutcome = m_hash.Calculate(nonSignatureHeaders);
+ if (!hashOutcome.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) non-signature headers.");
+ return false;
+ }
+
+ const auto nonSignatureHeadersHash = hashOutcome.GetResult();
+ stringToSign << HashingUtils::HexEncode(nonSignatureHeadersHash) << Aws::Auth::AWSAuthHelper::NEWLINE;
+
+ if (message.GetEventPayload().empty())
+ {
+ AWS_LOGSTREAM_WARN(v4StreamingLogTag, "Attempting to sign an empty message (no payload and no headers). "
+ "It is unlikely that this is the intended behavior.");
+ }
+ else
+ {
+ // use a preallocatedStreamBuf to avoid making a copy.
+ // The Hashing API requires either Aws::String or IStream as input.
+ // TODO: the hashing API should be accept 'unsigned char*' as input.
+ Utils::Stream::PreallocatedStreamBuf streamBuf(message.GetEventPayload().data(), message.GetEventPayload().size());
+ Aws::IOStream payload(&streamBuf);
+ hashOutcome = m_hash.Calculate(payload);
+
+ if (!hashOutcome.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to hash (sha256) non-signature headers.");
+ return false;
+ }
+ const auto payloadHash = hashOutcome.GetResult();
+ stringToSign << HashingUtils::HexEncode(payloadHash);
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Payload hash - " << HashingUtils::HexEncode(payloadHash));
+ }
+
+ Aws::Utils::ByteBuffer finalSignatureDigest = GenerateSignature(m_credentialsProvider->GetAWSCredentials(), stringToSign.str(), simpleDate, m_region, m_serviceName);
+ const auto finalSignature = HashingUtils::HexEncode(finalSignatureDigest);
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Final computed signing hash: " << finalSignature);
+ priorSignature = finalSignature;
+
+ message.InsertEventHeader(EVENTSTREAM_DATE_HEADER, EventHeaderValue(now.Millis(), EventHeaderValue::EventHeaderType::TIMESTAMP));
+ message.InsertEventHeader(EVENTSTREAM_SIGNATURE_HEADER, std::move(finalSignatureDigest));
+
+ AWS_LOGSTREAM_INFO(v4StreamingLogTag, "Event chunk final signature - " << finalSignature);
+ return true;
+}
+
+bool AWSAuthEventStreamV4Signer::ShouldSignHeader(const Aws::String& header) const
+{
+ return std::find(m_unsignedHeaders.cbegin(), m_unsignedHeaders.cend(), Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend();
+}
+
+Aws::Utils::ByteBuffer AWSAuthEventStreamV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign,
+ const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const
+{
+ Utils::Threading::ReaderLockGuard guard(m_derivedKeyLock);
+ const auto& secretKey = credentials.GetAWSSecretKey();
+ if (secretKey != m_currentSecretKey || simpleDate != m_currentDateStr)
+ {
+ guard.UpgradeToWriterLock();
+ // double-checked lock to prevent updating twice
+ if (m_currentDateStr != simpleDate || m_currentSecretKey != secretKey)
+ {
+ m_currentSecretKey = secretKey;
+ m_currentDateStr = simpleDate;
+ m_derivedKey = ComputeHash(m_currentSecretKey, m_currentDateStr, region, serviceName);
+ }
+
+ }
+ return GenerateSignature(stringToSign, m_derivedKey);
+}
+
+Aws::Utils::ByteBuffer AWSAuthEventStreamV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const
+{
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "Final String to sign: " << stringToSign);
+
+ Aws::StringStream ss;
+
+ auto hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Unable to hmac (sha256) final string");
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The final string is: \"" << stringToSign << "\"");
+ return {};
+ }
+
+ return hashResult.GetResult();
+}
+
+Aws::String AWSAuthEventStreamV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate,
+ const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const
+{
+ //generate the actual string we will use in signing the final request.
+ Aws::StringStream ss;
+
+ ss << Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256 << Aws::Auth::AWSAuthHelper::NEWLINE << dateValue << Aws::Auth::AWSAuthHelper::NEWLINE << simpleDate << "/" << region << "/"
+ << serviceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << Aws::Auth::AWSAuthHelper::NEWLINE << canonicalRequestHash;
+
+ return ss.str();
+}
+
+Aws::Utils::ByteBuffer AWSAuthEventStreamV4Signer::ComputeHash(const Aws::String& secretKey,
+ const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const
+{
+ Aws::String signingKey(Aws::Auth::AWSAuthHelper::SIGNING_KEY);
+ signingKey.append(secretKey);
+ auto hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()),
+ ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length()));
+
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\"");
+ return {};
+ }
+
+ auto kDate = hashResult.GetResult();
+ hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) region string \"" << region << "\"");
+ return {};
+ }
+
+ auto kRegion = hashResult.GetResult();
+ hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\"");
+ return {};
+ }
+
+ auto kService = hashResult.GetResult();
+ hashResult = m_HMAC.Calculate(ByteBuffer((unsigned char*)Aws::Auth::AWSAuthHelper::AWS4_REQUEST, strlen(Aws::Auth::AWSAuthHelper::AWS4_REQUEST)), kService);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4StreamingLogTag, "Unable to HMAC (SHA256) request string");
+ AWS_LOGSTREAM_DEBUG(v4StreamingLogTag, "The request string is: \"" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << "\"");
+ return {};
+ }
+ return hashResult.GetResult();
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp
new file mode 100644
index 0000000000..d26f41e6b3
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerCommon.cpp
@@ -0,0 +1,14 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/auth/signer/AWSAuthSignerCommon.h>
+
+namespace Aws
+{
+namespace Auth
+{
+const char SIGNATURE[] = "Signature";
+} // namespace Auth
+} // namespace Aws \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp
new file mode 100644
index 0000000000..5f7005d1da
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthSignerHelper.cpp
@@ -0,0 +1,103 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/auth/signer/AWSAuthSignerHelper.h>
+#include <aws/core/http/HttpTypes.h>
+
+#include <aws/core/http/HttpRequest.h>
+#include <aws/core/http/URI.h>
+#include <aws/core/utils/StringUtils.h>
+
+namespace Aws
+{
+namespace Auth
+{
+
+const char* AWSAuthHelper::EQ = "=";
+const char* AWSAuthHelper::AWS_HMAC_SHA256 = "AWS4-HMAC-SHA256";
+const char* AWSAuthHelper::AWS4_REQUEST = "aws4_request";
+const char* AWSAuthHelper::SIGNED_HEADERS = "SignedHeaders";
+const char* AWSAuthHelper::CREDENTIAL = "Credential";
+const char* AWSAuthHelper::NEWLINE = "\n";
+const char* AWSAuthHelper::X_AMZN_TRACE_ID = "x-amzn-trace-id";
+const char* AWSAuthHelper::X_AMZ_CONTENT_SHA256 = "x-amz-content-sha256";
+const char* AWSAuthHelper::SIGNING_KEY = "AWS4";
+const char* AWSAuthHelper::SIMPLE_DATE_FORMAT_STR = "%Y%m%d";
+
+Aws::String Aws::Auth::AWSAuthHelper::CanonicalizeRequestSigningString(Aws::Http::HttpRequest& request, bool urlEscapePath)
+{
+ request.CanonicalizeRequest();
+ Aws::StringStream signingStringStream;
+ signingStringStream << Aws::Http::HttpMethodMapper::GetNameForHttpMethod(request.GetMethod());
+
+ Aws::Http::URI uriCpy = request.GetUri();
+ // Many AWS services do not decode the URL before calculating SignatureV4 on their end.
+ // This results in the signature getting calculated with a double encoded URL.
+ // That means we have to double encode it here for the signature to match on the service side.
+ if(urlEscapePath)
+ {
+ // RFC3986 is how we encode the URL before sending it on the wire.
+ uriCpy.SetPath(uriCpy.GetURLEncodedPathRFC3986());
+ // However, SignatureV4 uses this URL encoding scheme
+ signingStringStream << AWSAuthHelper::NEWLINE << uriCpy.GetURLEncodedPath() << AWSAuthHelper::NEWLINE;
+ }
+ else
+ {
+ // For the services that DO decode the URL first; we don't need to double encode it.
+ signingStringStream << AWSAuthHelper::NEWLINE << uriCpy.GetURLEncodedPath() << AWSAuthHelper::NEWLINE;
+ }
+
+ if (request.GetQueryString().find('=') != std::string::npos)
+ {
+ signingStringStream << request.GetQueryString().substr(1) << AWSAuthHelper::NEWLINE;
+ }
+ else if (request.GetQueryString().size() > 1)
+ {
+ signingStringStream << request.GetQueryString().substr(1) << "=" << AWSAuthHelper::NEWLINE;
+ }
+ else
+ {
+ signingStringStream << AWSAuthHelper::NEWLINE;
+ }
+
+ return signingStringStream.str();
+}
+
+Aws::Http::HeaderValueCollection Aws::Auth::AWSAuthHelper::CanonicalizeHeaders(Aws::Http::HeaderValueCollection&& headers)
+{
+ Aws::Http::HeaderValueCollection canonicalHeaders;
+ for (const auto& header : headers)
+ {
+ auto trimmedHeaderName = Aws::Utils::StringUtils::Trim(header.first.c_str());
+ auto trimmedHeaderValue = Aws::Utils::StringUtils::Trim(header.second.c_str());
+
+ //multiline gets converted to line1,line2,etc...
+ auto headerMultiLine = Aws::Utils::StringUtils::SplitOnLine(trimmedHeaderValue);
+ Aws::String headerValue = headerMultiLine.size() == 0 ? "" : headerMultiLine[0];
+
+ if (headerMultiLine.size() > 1)
+ {
+ for(size_t i = 1; i < headerMultiLine.size(); ++i)
+ {
+ headerValue += " ";
+ headerValue += Aws::Utils::StringUtils::Trim(headerMultiLine[i].c_str());
+ }
+ }
+
+ //duplicate spaces need to be converted to one.
+ Aws::String::iterator new_end =
+ std::unique(headerValue.begin(), headerValue.end(),
+ [=](char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }
+ );
+ headerValue.erase(new_end, headerValue.end());
+
+ canonicalHeaders[trimmedHeaderName] = headerValue;
+ }
+
+ return canonicalHeaders;
+}
+
+} // namespace Auth
+} // namespace Aws \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp
new file mode 100644
index 0000000000..f8bfdbf867
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp
@@ -0,0 +1,580 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/auth/signer/AWSAuthV4Signer.h>
+#include <aws/core/auth/signer/AWSAuthSignerCommon.h>
+#include <aws/core/auth/signer/AWSAuthSignerHelper.h>
+
+#include <aws/core/auth/AWSCredentialsProvider.h>
+#include <aws/core/http/HttpRequest.h>
+#include <aws/core/http/URI.h>
+#include <aws/core/utils/DateTime.h>
+#include <aws/core/utils/HashingUtils.h>
+#include <aws/core/utils/Outcome.h>
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/utils/memory/AWSMemory.h>
+#include <aws/core/utils/crypto/Sha256.h>
+#include <aws/core/utils/crypto/Sha256HMAC.h>
+
+#include <aws/crt/auth/Credentials.h>
+#include <aws/crt/http/HttpRequestResponse.h>
+
+#include <iomanip>
+#include <cstring>
+
+using namespace Aws;
+using namespace Aws::Client;
+using namespace Aws::Auth;
+using namespace Aws::Http;
+using namespace Aws::Utils;
+using namespace Aws::Utils::Logging;
+
+static const char* X_AMZ_SIGNED_HEADERS = "X-Amz-SignedHeaders";
+static const char* X_AMZ_ALGORITHM = "X-Amz-Algorithm";
+static const char* X_AMZ_CREDENTIAL = "X-Amz-Credential";
+static const char* UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
+static const char* STREAMING_UNSIGNED_PAYLOAD_TRAILER = "STREAMING-UNSIGNED-PAYLOAD-TRAILER";
+static const char* X_AMZ_SIGNATURE = "X-Amz-Signature";
+static const char* USER_AGENT = "user-agent";
+static const char* EMPTY_STRING_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
+
+static const char v4LogTag[] = "AWSAuthV4Signer";
+static const char v4AsymmetricLogTag[] = "AWSAuthSymmetricV4Signer";
+
+namespace Aws
+{
+ namespace Auth
+ {
+ const char SIGV4_SIGNER[] = "SignatureV4";
+ const char ASYMMETRIC_SIGV4_SIGNER[] = "AsymmetricSignatureV4";
+ }
+}
+
+AWSAuthV4Signer::AWSAuthV4Signer(const std::shared_ptr<Auth::AWSCredentialsProvider>& credentialsProvider, const char* serviceName,
+ const Aws::String& region, PayloadSigningPolicy signingPolicy, bool urlEscapePath, AWSSigningAlgorithm signingAlgorithm) :
+ m_includeSha256HashHeader(true),
+ m_signingAlgorithm(signingAlgorithm),
+ m_credentialsProvider(credentialsProvider),
+ m_serviceName(serviceName),
+ m_region(region),
+ m_hash(Aws::MakeUnique<Aws::Utils::Crypto::Sha256>(v4LogTag)),
+ m_HMAC(Aws::MakeUnique<Aws::Utils::Crypto::Sha256HMAC>(v4LogTag)),
+ m_unsignedHeaders({USER_AGENT, Aws::Auth::AWSAuthHelper::X_AMZN_TRACE_ID}),
+ m_payloadSigningPolicy(signingPolicy),
+ m_urlEscapePath(urlEscapePath)
+{
+ //go ahead and warm up the signing cache.
+ ComputeHash(credentialsProvider->GetAWSCredentials().GetAWSSecretKey(), DateTime::CalculateGmtTimestampAsString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR), region, m_serviceName);
+}
+
+AWSAuthV4Signer::~AWSAuthV4Signer()
+{
+ // empty destructor in .cpp file to keep from needing the implementation of (AWSCredentialsProvider, Sha256, Sha256HMAC) in the header file
+}
+
+bool AWSAuthV4Signer::SignRequestWithSigV4a(Aws::Http::HttpRequest& request, const char* region, const char* serviceName,
+ bool signBody, long long expirationTimeInSeconds, Aws::Crt::Auth::SignatureType signatureType) const
+{
+ AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials();
+ auto crtCredentials = Aws::MakeShared<Aws::Crt::Auth::Credentials>(v4AsymmetricLogTag,
+ Aws::Crt::ByteCursorFromCString(credentials.GetAWSAccessKeyId().c_str()),
+ Aws::Crt::ByteCursorFromCString(credentials.GetAWSSecretKey().c_str()),
+ Aws::Crt::ByteCursorFromCString(credentials.GetSessionToken().c_str()),
+ credentials.GetExpiration().Seconds());
+
+ Aws::Crt::Auth::AwsSigningConfig awsSigningConfig;
+ awsSigningConfig.SetSigningAlgorithm(static_cast<Aws::Crt::Auth::SigningAlgorithm>(AWSSigningAlgorithm::ASYMMETRIC_SIGV4));
+ awsSigningConfig.SetSignatureType(signatureType);
+ awsSigningConfig.SetRegion(region);
+ awsSigningConfig.SetService(serviceName);
+ awsSigningConfig.SetSigningTimepoint(GetSigningTimestamp().UnderlyingTimestamp());
+ awsSigningConfig.SetUseDoubleUriEncode(m_urlEscapePath);
+ awsSigningConfig.SetShouldNormalizeUriPath(true);
+ awsSigningConfig.SetOmitSessionToken(false);
+ awsSigningConfig.SetShouldSignHeaderUserData(reinterpret_cast<void*>(const_cast<Aws::Set<Aws::String>*>(&m_unsignedHeaders)));
+ awsSigningConfig.SetShouldSignHeaderCallback([](const Aws::Crt::ByteCursor *name, void *user_data) {
+ Aws::Set<Aws::String>* unsignedHeaders = static_cast<Aws::Set<Aws::String>*>(user_data);
+ Aws::String headerKey(reinterpret_cast<const char*>(name->ptr), name->len);
+ return unsignedHeaders->find(Aws::Utils::StringUtils::ToLower(headerKey.c_str())) == unsignedHeaders->cend();
+ });
+ if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders)
+ {
+ Aws::String payloadHash(UNSIGNED_PAYLOAD);
+ if(signBody || request.GetUri().GetScheme() != Http::Scheme::HTTPS)
+ {
+ if (!request.GetContentBody())
+ {
+ AWS_LOGSTREAM_DEBUG(v4AsymmetricLogTag, "Using cached empty string sha256 " << EMPTY_STRING_SHA256 << " because payload is empty.");
+ payloadHash = EMPTY_STRING_SHA256;
+ }
+ else
+ {
+ // The hash will be calculated from the payload during signing.
+ payloadHash = {};
+ }
+ }
+ else
+ {
+ AWS_LOGSTREAM_DEBUG(v4AsymmetricLogTag, "Note: Http payloads are not being signed. signPayloads=" << signBody
+ << " http scheme=" << Http::SchemeMapper::ToString(request.GetUri().GetScheme()));
+ }
+ awsSigningConfig.SetSignedBodyValue(payloadHash.c_str());
+ awsSigningConfig.SetSignedBodyHeader(m_includeSha256HashHeader ? Aws::Crt::Auth::SignedBodyHeaderType::XAmzContentSha256 : Aws::Crt::Auth::SignedBodyHeaderType::None);
+ }
+ else if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams)
+ {
+ if (ServiceRequireUnsignedPayload(serviceName))
+ {
+ awsSigningConfig.SetSignedBodyValue(UNSIGNED_PAYLOAD);
+ }
+ else
+ {
+ awsSigningConfig.SetSignedBodyValue(EMPTY_STRING_SHA256);
+ }
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, "The signature type should be either \"HttpRequestViaHeaders\" or \"HttpRequestViaQueryParams\"");
+ return false;
+ }
+ awsSigningConfig.SetExpirationInSeconds(static_cast<uint64_t>(expirationTimeInSeconds));
+ awsSigningConfig.SetCredentials(crtCredentials);
+
+ std::shared_ptr<Aws::Crt::Http::HttpRequest> crtHttpRequest = request.ToCrtHttpRequest();
+
+ auto sigv4HttpRequestSigner = Aws::MakeShared<Aws::Crt::Auth::Sigv4HttpRequestSigner>(v4AsymmetricLogTag);
+ bool success = true;
+ sigv4HttpRequestSigner->SignRequest(crtHttpRequest, awsSigningConfig,
+ [&request, &success, signatureType](const std::shared_ptr<Aws::Crt::Http::HttpRequest>& signedCrtHttpRequest, int errorCode) {
+ success = (errorCode == AWS_ERROR_SUCCESS);
+ if (success)
+ {
+ if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders)
+ {
+ for (size_t i = 0; i < signedCrtHttpRequest->GetHeaderCount(); i++)
+ {
+ Aws::Crt::Optional<Aws::Crt::Http::HttpHeader> httpHeader = signedCrtHttpRequest->GetHeader(i);
+ request.SetHeaderValue(Aws::String(reinterpret_cast<const char*>(httpHeader->name.ptr), httpHeader->name.len),
+ Aws::String(reinterpret_cast<const char*>(httpHeader->value.ptr), httpHeader->value.len));
+ }
+ }
+ else if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams)
+ {
+ Aws::Http::URI newPath(reinterpret_cast<const char*>(signedCrtHttpRequest->GetPath()->ptr));
+ request.GetUri().SetQueryString(newPath.GetQueryString());
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, "No action to take when signature type is neither \"HttpRequestViaHeaders\" nor \"HttpRequestViaQueryParams\"");
+ success = false;
+ }
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(v4AsymmetricLogTag, "Encountered internal error during signing process with AWS signature version 4 (Asymmetric):" << aws_error_str(errorCode));
+ }
+ }
+ );
+ return success;
+}
+
+bool AWSAuthV4Signer::ShouldSignHeader(const Aws::String& header) const
+{
+ return m_unsignedHeaders.find(Aws::Utils::StringUtils::ToLower(header.c_str())) == m_unsignedHeaders.cend();
+}
+
+bool AWSAuthV4Signer::SignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, bool signBody) const
+{
+ Aws::String signingRegion = region ? region : m_region;
+ Aws::String signingServiceName = serviceName ? serviceName : m_serviceName;
+ AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials();
+
+ //don't sign anonymous requests
+ if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty())
+ {
+ return true;
+ }
+
+ request.SetSigningAccessKey(credentials.GetAWSAccessKeyId());
+ request.SetSigningRegion(signingRegion);
+
+ Aws::String payloadHash(UNSIGNED_PAYLOAD);
+ switch(m_payloadSigningPolicy)
+ {
+ case PayloadSigningPolicy::Always:
+ signBody = true;
+ break;
+ case PayloadSigningPolicy::Never:
+ signBody = false;
+ break;
+ case PayloadSigningPolicy::RequestDependent:
+ // respect the request setting
+ default:
+ break;
+ }
+
+ if (m_signingAlgorithm == AWSSigningAlgorithm::ASYMMETRIC_SIGV4)
+ {
+ // Replace m_serviceName with signingServiceName after rebasing on S3 outposts.
+ return SignRequestWithSigV4a(request, signingRegion.c_str(), m_serviceName.c_str(), signBody,
+ 0 /* expirationTimeInSeconds doesn't matter for HttpRequestViaHeaders */, Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders);
+ }
+
+ if (!credentials.GetSessionToken().empty())
+ {
+ request.SetAwsSessionToken(credentials.GetSessionToken());
+ }
+
+ if(signBody || request.GetUri().GetScheme() != Http::Scheme::HTTPS)
+ {
+ payloadHash = ComputePayloadHash(request);
+ if (payloadHash.empty())
+ {
+ return false;
+ }
+ if (request.GetRequestHash().second != nullptr)
+ {
+ Aws::String checksumHeaderKey = Aws::String("x-amz-checksum-") + request.GetRequestHash().first;
+ Aws::String checksumHeaderValue = HashingUtils::Base64Encode(request.GetRequestHash().second->Calculate(*(request.GetContentBody())).GetResult());
+ request.SetHeaderValue(checksumHeaderKey, checksumHeaderValue);
+ request.SetRequestHash("", nullptr);
+ }
+ }
+ else
+ {
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Note: Http payloads are not being signed. signPayloads=" << signBody
+ << " http scheme=" << Http::SchemeMapper::ToString(request.GetUri().GetScheme()));
+ if (request.GetRequestHash().second != nullptr)
+ {
+ payloadHash = STREAMING_UNSIGNED_PAYLOAD_TRAILER;
+ Aws::String trailerHeaderValue = Aws::String("x-amz-checksum-") + request.GetRequestHash().first;
+ request.SetHeaderValue(Http::AWS_TRAILER_HEADER, trailerHeaderValue);
+ request.SetTransferEncoding(CHUNKED_VALUE);
+ request.SetHeaderValue(Http::CONTENT_ENCODING_HEADER, Http::AWS_CHUNKED_VALUE);
+ request.SetHeaderValue(Http::DECODED_CONTENT_LENGTH_HEADER, request.GetHeaderValue(Http::CONTENT_LENGTH_HEADER));
+ request.DeleteHeader(Http::CONTENT_LENGTH_HEADER);
+ }
+ }
+
+ if(m_includeSha256HashHeader)
+ {
+ request.SetHeaderValue(Aws::Auth::AWSAuthHelper::X_AMZ_CONTENT_SHA256, payloadHash);
+ }
+
+ //calculate date header to use in internal signature (this also goes into date header).
+ DateTime now = GetSigningTimestamp();
+ Aws::String dateHeaderValue = now.ToGmtString(DateFormat::ISO_8601_BASIC);
+ request.SetHeaderValue(AWS_DATE_HEADER, dateHeaderValue);
+
+ Aws::StringStream headersStream;
+ Aws::StringStream signedHeadersStream;
+
+ for (const auto& header : Aws::Auth::AWSAuthHelper::CanonicalizeHeaders(request.GetHeaders()))
+ {
+ if(ShouldSignHeader(header.first))
+ {
+ headersStream << header.first.c_str() << ":" << header.second.c_str() << Aws::Auth::AWSAuthHelper::NEWLINE;
+ signedHeadersStream << header.first.c_str() << ";";
+ }
+ }
+
+ Aws::String canonicalHeadersString = headersStream.str();
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString);
+
+ //calculate signed headers parameter
+ Aws::String signedHeadersValue = signedHeadersStream.str();
+ //remove that last semi-colon
+ if (!signedHeadersValue.empty())
+ {
+ signedHeadersValue.pop_back();
+ }
+
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value:" << signedHeadersValue);
+
+ //generate generalized canonicalized request string.
+ Aws::String canonicalRequestString = Aws::Auth::AWSAuthHelper::CanonicalizeRequestSigningString(request, m_urlEscapePath);
+
+ //append v4 stuff to the canonical request string.
+ canonicalRequestString.append(canonicalHeadersString);
+ canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE);
+ canonicalRequestString.append(signedHeadersValue);
+ canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE);
+ canonicalRequestString.append(payloadHash);
+
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString);
+
+ //now compute sha256 on that request string
+ auto hashResult = m_hash->Calculate(canonicalRequestString);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string");
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\"");
+ return false;
+ }
+
+ auto sha256Digest = hashResult.GetResult();
+ Aws::String canonicalRequestHash = HashingUtils::HexEncode(sha256Digest);
+ Aws::String simpleDate = now.ToGmtString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR);
+
+ Aws::String stringToSign = GenerateStringToSign(dateHeaderValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName);
+ auto finalSignature = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName);
+
+ Aws::StringStream ss;
+ ss << Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256 << " " << Aws::Auth::AWSAuthHelper::CREDENTIAL << Aws::Auth::AWSAuthHelper::EQ << credentials.GetAWSAccessKeyId() << "/" << simpleDate
+ << "/" << signingRegion << "/" << signingServiceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << ", " << Aws::Auth::AWSAuthHelper::SIGNED_HEADERS << Aws::Auth::AWSAuthHelper::EQ
+ << signedHeadersValue << ", " << SIGNATURE << Aws::Auth::AWSAuthHelper::EQ << finalSignature;
+
+ auto awsAuthString = ss.str();
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Signing request with: " << awsAuthString);
+ request.SetAwsAuthorization(awsAuthString);
+ return true;
+}
+
+bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, long long expirationTimeInSeconds) const
+{
+ return PresignRequest(request, m_region.c_str(), expirationTimeInSeconds);
+}
+
+bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, long long expirationInSeconds) const
+{
+ return PresignRequest(request, region, m_serviceName.c_str(), expirationInSeconds);
+}
+
+bool AWSAuthV4Signer::PresignRequest(Aws::Http::HttpRequest& request, const char* region, const char* serviceName, long long expirationTimeInSeconds) const
+{
+ Aws::String signingRegion = region ? region : m_region;
+ Aws::String signingServiceName = serviceName ? serviceName : m_serviceName;
+ AWSCredentials credentials = m_credentialsProvider->GetAWSCredentials();
+
+ //don't sign anonymous requests
+ if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty())
+ {
+ return true;
+ }
+
+ if (m_signingAlgorithm == AWSSigningAlgorithm::ASYMMETRIC_SIGV4)
+ {
+ return SignRequestWithSigV4a(request, signingRegion.c_str(), signingServiceName.c_str(), false /* signBody doesn't matter for HttpRequestViaHeaders */,
+ expirationTimeInSeconds, Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams);
+ }
+
+ Aws::StringStream intConversionStream;
+ intConversionStream << expirationTimeInSeconds;
+ request.AddQueryStringParameter(Http::X_AMZ_EXPIRES_HEADER, intConversionStream.str());
+
+ if (!credentials.GetSessionToken().empty())
+ {
+ request.AddQueryStringParameter(Http::AWS_SECURITY_TOKEN, credentials.GetSessionToken());
+ }
+
+ //calculate date header to use in internal signature (this also goes into date header).
+ DateTime now = GetSigningTimestamp();
+ Aws::String dateQueryValue = now.ToGmtString(DateFormat::ISO_8601_BASIC);
+ request.AddQueryStringParameter(Http::AWS_DATE_HEADER, dateQueryValue);
+
+ Aws::StringStream headersStream;
+ Aws::StringStream signedHeadersStream;
+ for (const auto& header : Aws::Auth::AWSAuthHelper::CanonicalizeHeaders(request.GetHeaders()))
+ {
+ if(ShouldSignHeader(header.first))
+ {
+ headersStream << header.first.c_str() << ":" << header.second.c_str() << Aws::Auth::AWSAuthHelper::NEWLINE;
+ signedHeadersStream << header.first.c_str() << ";";
+ }
+ }
+
+ Aws::String canonicalHeadersString = headersStream.str();
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Header String: " << canonicalHeadersString);
+
+ //calculate signed headers parameter
+ Aws::String signedHeadersValue(signedHeadersStream.str());
+ //remove that last semi-colon
+ if (!signedHeadersValue.empty())
+ {
+ signedHeadersValue.pop_back();
+ }
+
+ request.AddQueryStringParameter(X_AMZ_SIGNED_HEADERS, signedHeadersValue);
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Signed Headers value: " << signedHeadersValue);
+
+ Aws::StringStream ss;
+ Aws::String simpleDate = now.ToGmtString(Aws::Auth::AWSAuthHelper::SIMPLE_DATE_FORMAT_STR);
+ ss << credentials.GetAWSAccessKeyId() << "/" << simpleDate
+ << "/" << signingRegion << "/" << signingServiceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST;
+
+ request.AddQueryStringParameter(X_AMZ_ALGORITHM, Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256);
+ request.AddQueryStringParameter(X_AMZ_CREDENTIAL, ss.str());
+ ss.str("");
+
+ request.SetSigningAccessKey(credentials.GetAWSAccessKeyId());
+ request.SetSigningRegion(signingRegion);
+
+ //generate generalized canonicalized request string.
+ Aws::String canonicalRequestString = Aws::Auth::AWSAuthHelper::CanonicalizeRequestSigningString(request, m_urlEscapePath);
+
+ //append v4 stuff to the canonical request string.
+ canonicalRequestString.append(canonicalHeadersString);
+ canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE);
+ canonicalRequestString.append(signedHeadersValue);
+ canonicalRequestString.append(Aws::Auth::AWSAuthHelper::NEWLINE);
+ if (ServiceRequireUnsignedPayload(signingServiceName))
+ {
+ canonicalRequestString.append(UNSIGNED_PAYLOAD);
+ }
+ else
+ {
+ canonicalRequestString.append(EMPTY_STRING_SHA256);
+ }
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Canonical Request String: " << canonicalRequestString);
+
+ //now compute sha256 on that request string
+ auto hashResult = m_hash->Calculate(canonicalRequestString);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to hash (sha256) request string");
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << canonicalRequestString << "\"");
+ return false;
+ }
+
+ auto sha256Digest = hashResult.GetResult();
+ auto canonicalRequestHash = HashingUtils::HexEncode(sha256Digest);
+
+ auto stringToSign = GenerateStringToSign(dateQueryValue, simpleDate, canonicalRequestHash, signingRegion, signingServiceName);
+ auto finalSigningHash = GenerateSignature(credentials, stringToSign, simpleDate, signingRegion, signingServiceName);
+ if (finalSigningHash.empty())
+ {
+ return false;
+ }
+
+ //add that the signature to the query string
+ request.AddQueryStringParameter(X_AMZ_SIGNATURE, finalSigningHash);
+
+ return true;
+}
+
+bool AWSAuthV4Signer::ServiceRequireUnsignedPayload(const Aws::String& serviceName) const
+{
+ // S3 uses a magic string (instead of the empty string) for its body hash for presigned URLs as outlined here:
+ // https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
+ // this is true for PUT, POST, GET, DELETE and HEAD operations.
+ // However, other services (for example RDS) implement the specification as outlined here:
+ // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
+ // which states that body-less requests should use the empty-string SHA256 hash.
+ return "s3" == serviceName || "s3-object-lambda" == serviceName;
+}
+
+Aws::String AWSAuthV4Signer::GenerateSignature(const AWSCredentials& credentials, const Aws::String& stringToSign,
+ const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const
+{
+ auto key = ComputeHash(credentials.GetAWSSecretKey(), simpleDate, region, serviceName);
+ return GenerateSignature(stringToSign, key);
+}
+
+Aws::String AWSAuthV4Signer::GenerateSignature(const Aws::String& stringToSign, const ByteBuffer& key) const
+{
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Final String to sign: " << stringToSign);
+
+ Aws::StringStream ss;
+
+ auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)stringToSign.c_str(), stringToSign.length()), key);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hmac (sha256) final string");
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "The final string is: \"" << stringToSign << "\"");
+ return {};
+ }
+
+ //now we finally sign our request string with our hex encoded derived hash.
+ auto finalSigningDigest = hashResult.GetResult();
+
+ auto finalSigningHash = HashingUtils::HexEncode(finalSigningDigest);
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Final computed signing hash: " << finalSigningHash);
+
+ return finalSigningHash;
+}
+
+Aws::String AWSAuthV4Signer::ComputePayloadHash(Aws::Http::HttpRequest& request) const
+{
+ if (!request.GetContentBody())
+ {
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Using cached empty string sha256 " << EMPTY_STRING_SHA256 << " because payload is empty.");
+ return EMPTY_STRING_SHA256;
+ }
+
+ //compute hash on payload if it exists.
+ auto hashResult = m_hash->Calculate(*request.GetContentBody());
+
+ if(request.GetContentBody())
+ {
+ request.GetContentBody()->clear();
+ request.GetContentBody()->seekg(0);
+ }
+
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to hash (sha256) request body");
+ return {};
+ }
+
+ auto sha256Digest = hashResult.GetResult();
+
+ Aws::String payloadHash(HashingUtils::HexEncode(sha256Digest));
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "Calculated sha256 " << payloadHash << " for payload.");
+ return payloadHash;
+}
+
+Aws::String AWSAuthV4Signer::GenerateStringToSign(const Aws::String& dateValue, const Aws::String& simpleDate,
+ const Aws::String& canonicalRequestHash, const Aws::String& region, const Aws::String& serviceName) const
+{
+ //generate the actual string we will use in signing the final request.
+ Aws::StringStream ss;
+
+ ss << Aws::Auth::AWSAuthHelper::AWS_HMAC_SHA256 << Aws::Auth::AWSAuthHelper::NEWLINE << dateValue << Aws::Auth::AWSAuthHelper::NEWLINE << simpleDate << "/" << region << "/"
+ << serviceName << "/" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << Aws::Auth::AWSAuthHelper::NEWLINE << canonicalRequestHash;
+
+ return ss.str();
+}
+
+Aws::Utils::ByteBuffer AWSAuthV4Signer::ComputeHash(const Aws::String& secretKey,
+ const Aws::String& simpleDate, const Aws::String& region, const Aws::String& serviceName) const
+{
+ Aws::String signingKey(Aws::Auth::AWSAuthHelper::SIGNING_KEY);
+ signingKey.append(secretKey);
+ auto hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)simpleDate.c_str(), simpleDate.length()),
+ ByteBuffer((unsigned char*)signingKey.c_str(), signingKey.length()));
+
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) date string \"" << simpleDate << "\"");
+ return {};
+ }
+
+ auto kDate = hashResult.GetResult();
+ hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)region.c_str(), region.length()), kDate);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) region string \"" << region << "\"");
+ return {};
+ }
+
+ auto kRegion = hashResult.GetResult();
+ hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)serviceName.c_str(), serviceName.length()), kRegion);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4LogTag, "Failed to HMAC (SHA256) service string \"" << m_serviceName << "\"");
+ return {};
+ }
+
+ auto kService = hashResult.GetResult();
+ hashResult = m_HMAC->Calculate(ByteBuffer((unsigned char*)Aws::Auth::AWSAuthHelper::AWS4_REQUEST, strlen(Aws::Auth::AWSAuthHelper::AWS4_REQUEST)), kService);
+ if (!hashResult.IsSuccess())
+ {
+ AWS_LOGSTREAM_ERROR(v4LogTag, "Unable to HMAC (SHA256) request string");
+ AWS_LOGSTREAM_DEBUG(v4LogTag, "The request string is: \"" << Aws::Auth::AWSAuthHelper::AWS4_REQUEST << "\"");
+ return {};
+ }
+ return hashResult.GetResult();
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp
new file mode 100644
index 0000000000..d94cb421f2
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/auth/signer/AWSNullSigner.cpp
@@ -0,0 +1,14 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/auth/signer/AWSNullSigner.h>
+
+namespace Aws
+{
+ namespace Auth
+ {
+ const char NULL_SIGNER[] = "NullSigner";
+ }
+}