8#include <smithy/identity/signer/AwsSignerBase.h>
9#include <smithy/identity/identity/AwsCredentialIdentityBase.h>
10#include <aws/core/auth/AWSCredentials.h>
11#include <aws/crt/auth/Credentials.h>
13#include <aws/core/http/HttpRequest.h>
14#include <aws/core/auth/signer/AWSAuthSignerHelper.h>
15#include <aws/crt/http/HttpConnection.h>
16#include <aws/crt/http/HttpRequestResponse.h>
17#include <condition_variable>
19#include <smithy/identity/signer/built-in/SignerProperties.h>
20#include <smithy/identity/auth/AuthSchemeResolverBase.h>
24 static const char*
EMPTY_STRING_SHA256 =
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
62 Aws::Crt::Auth::SignatureType signatureType = Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams;
77 if (credentials.GetAWSAccessKeyId().empty() || credentials.GetAWSSecretKey().empty())
81 return sign(httpRequest, identity, properties, signingRegion, signingServiceName, expirationTimeInSeconds, signatureType);
88 std::shared_ptr<Aws::Crt::Auth::Credentials>& crtCredentials,
92 Aws::Crt::Auth::AwsSigningConfig& awsSigningConfig,
94 Aws::Crt::Auth::SignatureType signatureType)
const
97 awsSigningConfig.SetSignatureType(signatureType);
98 awsSigningConfig.SetRegion(serviceName.c_str());
99 awsSigningConfig.SetService(region.c_str());
101 awsSigningConfig.SetUseDoubleUriEncode(
m_urlEscape);
102 awsSigningConfig.SetShouldNormalizeUriPath(
true);
103 awsSigningConfig.SetOmitSessionToken(
false);
105 awsSigningConfig.SetShouldSignHeaderCallback([](
const Aws::Crt::ByteCursor *name,
void *user_data) {
107 Aws::String headerKey(
reinterpret_cast<const char*
>(name->ptr), name->len);
110 if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders)
128 AWS_LOGSTREAM_DEBUG(
v4AsymmetricLogTag,
"Note: Http payloads are not being signed. signPayloads=" << signBody
131 awsSigningConfig.SetSignedBodyValue(payloadHash.c_str());
132 awsSigningConfig.SetSignedBodyHeader(
m_includeSha256HashHeader ? Aws::Crt::Auth::SignedBodyHeaderType::XAmzContentSha256 : Aws::Crt::Auth::SignedBodyHeaderType::None);
134 else if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams)
147 AWS_LOGSTREAM_ERROR(
v4AsymmetricLogTag,
"The signature type should be either \"HttpRequestViaHeaders\" or \"HttpRequestViaQueryParams\"");
151 awsSigningConfig.SetCredentials(crtCredentials);
157 Aws::Crt::Auth::SignatureType signatureType)
174 auto signPayloadIt = properties.find(
"SignPayload");
175 bool signPayload = signPayloadIt != properties.end() ? signPayloadIt->second.get<
Aws::String>() ==
"true" :
false;
178 auto regionOverride = signerRegionOverrideIt != properties.end() ? signerRegionOverrideIt->second.get<
Aws::String>().c_str() : region.c_str();
181 auto serviceName = signerServiceNameOverrideIt != properties.end() ? signerServiceNameOverrideIt->second.get<
Aws::String>().c_str() : svcName.c_str();
183 auto &request = *httpRequest;
186 if (legacyCreds.GetAWSAccessKeyId().empty() || legacyCreds.GetAWSSecretKey().empty())
191 httpRequest->SetSigningAccessKey(legacyCreds.GetAWSAccessKeyId());
192 httpRequest->SetSigningRegion(regionOverride);
194 auto crtCredentials = Aws::MakeShared<Aws::Crt::Auth::Credentials>(
v4AsymmetricLogTag,
195 Aws::Crt::ByteCursorFromCString(identity.
accessKeyId().c_str()),
197 Aws::Crt::ByteCursorFromCString((*identity.
sessionToken()).c_str()),
200 Aws::Crt::Auth::AwsSigningConfig awsSigningConfig;
202 bool success =
createAwsSigningConfig(crtCredentials, request, serviceName, regionOverride, awsSigningConfig, signPayload, signatureType);
211 awsSigningConfig.SetRegion(regionOverride);
212 awsSigningConfig.SetService(serviceName);
213 awsSigningConfig.SetExpirationInSeconds(expirationTimeInSeconds);
215 std::shared_ptr<Aws::Crt::Http::HttpRequest> crtHttpRequest = request.ToCrtHttpRequest();
217 auto sigv4HttpRequestSigner = Aws::MakeShared<Aws::Crt::Auth::Sigv4HttpRequestSigner>(
v4AsymmetricLogTag);
220 bool processed =
false;
222 sigv4HttpRequestSigner->SignRequest(crtHttpRequest, awsSigningConfig,
223 [&request, &success, &errorMessage, &processed,
this, signatureType](
const std::shared_ptr<Aws::Crt::Http::HttpRequest>& signedCrtHttpRequest,
int errorCode) {
224 std::unique_lock<std::mutex> lock(
m_mutex);
225 m_cv.wait(lock, [&]{
return !processed; });
226 success = (errorCode == AWS_ERROR_SUCCESS);
229 if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders)
231 for (
size_t i = 0; i < signedCrtHttpRequest->GetHeaderCount(); i++)
233 Aws::Crt::Optional<Aws::Crt::Http::HttpHeader> httpHeader = signedCrtHttpRequest->GetHeader(i);
234 request.SetHeaderValue(
Aws::String(
reinterpret_cast<const char*
>(httpHeader->name.ptr), httpHeader->name.len),
235 Aws::String(
reinterpret_cast<const char*
>(httpHeader->value.ptr), httpHeader->value.len));
238 else if (signatureType == Aws::Crt::Auth::SignatureType::HttpRequestViaQueryParams)
240 Aws::Http::URI newPath(
reinterpret_cast<const char*
>(signedCrtHttpRequest->GetPath()->ptr));
245 errorMessage =
"No action to take when signature type is neither \"HttpRequestViaHeaders\" nor \"HttpRequestViaQueryParams\"";
253 errStream <<
"Encountered internal error during signing process with AWS signature version 4 (Asymmetric):" << aws_error_str(errorCode);
254 errorMessage = errStream.str();
265 std::unique_lock<std::mutex> lock(
m_mutex);
266 m_cv.wait(lock, [&]{
return processed; });
282 return "s3" == serviceName ||
"s3-object-lambda" == serviceName;
287 std::shared_ptr<Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy>
m_policy;
293 const Aws::Crt::Auth::SignatureType
m_signatureType{Aws::Crt::Auth::SignatureType::HttpRequestViaHeaders};
virtual const std::shared_ptr< Aws::IOStream > & GetContentBody() const =0
const Aws::String & GetQueryString() const
static Aws::String ToLower(const char *source)
virtual Aws::String accessKeyId() const =0
virtual Aws::Crt::Optional< AwsIdentity::DateTime > expiration() const override=0
virtual Aws::String secretAccessKey() const =0
virtual Aws::Crt::Optional< Aws::String > sessionToken() const =0
std::condition_variable m_cv
const Aws::Crt::Auth::SignatureType m_signatureType
bool createAwsSigningConfig(std::shared_ptr< Aws::Crt::Auth::Credentials > &crtCredentials, const Aws::Http::HttpRequest &request, const Aws::String &serviceName, const Aws::String ®ion, Aws::Crt::Auth::AwsSigningConfig &awsSigningConfig, bool signBody, Aws::Crt::Auth::SignatureType signatureType) const
bool ServiceRequireUnsignedPayload(const Aws::String &serviceName) const
std::shared_ptr< Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy > m_policy
virtual ~AwsSigV4aSigner()
AwsSigV4aSigner(const Aws::String &serviceName, const Aws::String ®ion, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy policy)
AwsSigV4aSigner(const Aws::String &serviceName, const Aws::String ®ion)
const Aws::Set< Aws::String > m_unsignedHeaders
long long m_expirationTimeInSeconds
const bool m_includeSha256HashHeader
AwsSigV4aSigner(const Aws::String &serviceName, const Aws::String ®ion, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy policy, bool urlEscape)
SigningFutureOutcome sign(std::shared_ptr< HttpRequest > httpRequest, const AwsCredentialIdentityBase &identity, SigningProperties properties) override
Aws::String m_serviceName
SigningFutureOutcome presign(std::shared_ptr< HttpRequest > httpRequest, const AwsCredentialIdentityBase &identity, SigningProperties properties, const Aws::String ®ion, const Aws::String &serviceName, long long expirationTimeInSeconds) override
SigningFutureOutcome sign(std::shared_ptr< HttpRequest > httpRequest, const AwsCredentialIdentityBase &identity, SigningProperties properties, const Aws::String ®ion, const Aws::String &svcName, long long expirationTimeInSeconds, Aws::Crt::Auth::SignatureType signatureType)
Aws::Client::AWSError< Aws::Client::CoreErrors > SigningError
Aws::Utils::FutureOutcome< std::shared_ptr< HttpRequest >, SigningError > SigningFutureOutcome
Aws::UnorderedMap< Aws::String, Aws::Crt::Variant< Aws::String, bool > > SigningProperties
virtual Aws::Utils::DateTime GetSigningTimestamp() const
AWS_CORE_API const char * ToString(Scheme scheme)
std::basic_string< char, std::char_traits< char >, Aws::Allocator< char > > String
std::set< T, std::less< T >, Aws::Allocator< T > > Set
std::basic_ostringstream< char, std::char_traits< char >, Aws::Allocator< char > > OStringStream
static const char v4AsymmetricLogTag[]
SMITHY_API const char * SIGNER_REGION_PROPERTY
static const char * UNSIGNED_PAYLOAD
static const char * EMPTY_STRING_SHA256
SMITHY_API const char * SIGNER_SERVICE_NAME
static const char * X_AMZN_TRACE_ID
static const char * USER_AGENT