Sigv4Signing.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/crt/auth/Sigv4Signing.h>
  6. #include <aws/crt/auth/Credentials.h>
  7. #include <aws/crt/http/HttpRequestResponse.h>
  8. #include <aws/auth/signable.h>
  9. #include <aws/auth/signing.h>
  10. #include <aws/auth/signing_result.h>
  11. namespace Aws
  12. {
  13. namespace Crt
  14. {
  15. namespace Auth
  16. {
  17. namespace SignedBodyValue
  18. {
  19. const char *EmptySha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
  20. const char *EmptySha256Str() { return EmptySha256; }
  21. const char *UnsignedPayload = "UNSIGNED-PAYLOAD";
  22. const char *UnsignedPayloadStr() { return UnsignedPayload; }
  23. const char *StreamingAws4HmacSha256Payload = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD";
  24. const char *StreamingAws4HmacSha256PayloadStr() { return StreamingAws4HmacSha256Payload; }
  25. const char *StreamingAws4HmacSha256Events = "STREAMING-AWS4-HMAC-SHA256-EVENTS";
  26. const char *StreamingAws4HmacSha256EventsStr() { return StreamingAws4HmacSha256Events; }
  27. } // namespace SignedBodyValue
  28. AwsSigningConfig::AwsSigningConfig(Allocator *allocator)
  29. : ISigningConfig(), m_allocator(allocator), m_credentialsProvider(nullptr), m_credentials(nullptr)
  30. {
  31. AWS_ZERO_STRUCT(m_config);
  32. SetSigningAlgorithm(SigningAlgorithm::SigV4);
  33. SetSignatureType(SignatureType::HttpRequestViaHeaders);
  34. SetShouldNormalizeUriPath(true);
  35. SetUseDoubleUriEncode(true);
  36. SetOmitSessionToken(false);
  37. SetSignedBodyHeader(SignedBodyHeaderType::None);
  38. SetSigningTimepoint(DateTime::Now());
  39. SetExpirationInSeconds(0);
  40. m_config.config_type = AWS_SIGNING_CONFIG_AWS;
  41. }
  42. AwsSigningConfig::~AwsSigningConfig() { m_allocator = nullptr; }
  43. SigningAlgorithm AwsSigningConfig::GetSigningAlgorithm() const noexcept
  44. {
  45. return static_cast<SigningAlgorithm>(m_config.algorithm);
  46. }
  47. void AwsSigningConfig::SetSigningAlgorithm(SigningAlgorithm algorithm) noexcept
  48. {
  49. m_config.algorithm = static_cast<aws_signing_algorithm>(algorithm);
  50. }
  51. SignatureType AwsSigningConfig::GetSignatureType() const noexcept
  52. {
  53. return static_cast<SignatureType>(m_config.signature_type);
  54. }
  55. void AwsSigningConfig::SetSignatureType(SignatureType signatureType) noexcept
  56. {
  57. m_config.signature_type = static_cast<aws_signature_type>(signatureType);
  58. }
  59. const Crt::String &AwsSigningConfig::GetRegion() const noexcept { return m_signingRegion; }
  60. void AwsSigningConfig::SetRegion(const Crt::String &region) noexcept
  61. {
  62. m_signingRegion = region;
  63. m_config.region = ByteCursorFromCString(m_signingRegion.c_str());
  64. }
  65. const Crt::String &AwsSigningConfig::GetService() const noexcept { return m_serviceName; }
  66. void AwsSigningConfig::SetService(const Crt::String &service) noexcept
  67. {
  68. m_serviceName = service;
  69. m_config.service = ByteCursorFromCString(m_serviceName.c_str());
  70. }
  71. DateTime AwsSigningConfig::GetSigningTimepoint() const noexcept
  72. {
  73. return {aws_date_time_as_millis(&m_config.date)};
  74. }
  75. void AwsSigningConfig::SetSigningTimepoint(const DateTime &date) noexcept
  76. {
  77. aws_date_time_init_epoch_millis(&m_config.date, date.Millis());
  78. }
  79. bool AwsSigningConfig::GetUseDoubleUriEncode() const noexcept
  80. {
  81. return m_config.flags.use_double_uri_encode;
  82. }
  83. void AwsSigningConfig::SetUseDoubleUriEncode(bool useDoubleUriEncode) noexcept
  84. {
  85. m_config.flags.use_double_uri_encode = useDoubleUriEncode;
  86. }
  87. bool AwsSigningConfig::GetShouldNormalizeUriPath() const noexcept
  88. {
  89. return m_config.flags.should_normalize_uri_path;
  90. }
  91. void AwsSigningConfig::SetShouldNormalizeUriPath(bool shouldNormalizeUriPath) noexcept
  92. {
  93. m_config.flags.should_normalize_uri_path = shouldNormalizeUriPath;
  94. }
  95. bool AwsSigningConfig::GetOmitSessionToken() const noexcept { return m_config.flags.omit_session_token; }
  96. void AwsSigningConfig::SetOmitSessionToken(bool omitSessionToken) noexcept
  97. {
  98. m_config.flags.omit_session_token = omitSessionToken;
  99. }
  100. ShouldSignHeaderCb AwsSigningConfig::GetShouldSignHeaderCallback() const noexcept
  101. {
  102. return m_config.should_sign_header;
  103. }
  104. void AwsSigningConfig::SetShouldSignHeaderCallback(ShouldSignHeaderCb shouldSignHeaderCb) noexcept
  105. {
  106. m_config.should_sign_header = shouldSignHeaderCb;
  107. }
  108. void *AwsSigningConfig::GetShouldSignHeaderUserData() const noexcept
  109. {
  110. return m_config.should_sign_header_ud;
  111. }
  112. void AwsSigningConfig::SetShouldSignHeaderUserData(void *userData) noexcept
  113. {
  114. m_config.should_sign_header_ud = userData;
  115. }
  116. const Crt::String &AwsSigningConfig::GetSignedBodyValue() const noexcept { return m_signedBodyValue; }
  117. void AwsSigningConfig::SetSignedBodyValue(const Crt::String &signedBodyValue) noexcept
  118. {
  119. m_signedBodyValue = signedBodyValue;
  120. m_config.signed_body_value = ByteCursorFromString(m_signedBodyValue);
  121. }
  122. SignedBodyHeaderType AwsSigningConfig::GetSignedBodyHeader() const noexcept
  123. {
  124. return static_cast<SignedBodyHeaderType>(m_config.signed_body_header);
  125. }
  126. void AwsSigningConfig::SetSignedBodyHeader(SignedBodyHeaderType signedBodyHeader) noexcept
  127. {
  128. m_config.signed_body_header = static_cast<enum aws_signed_body_header_type>(signedBodyHeader);
  129. }
  130. uint64_t AwsSigningConfig::GetExpirationInSeconds() const noexcept
  131. {
  132. return m_config.expiration_in_seconds;
  133. }
  134. void AwsSigningConfig::SetExpirationInSeconds(uint64_t expirationInSeconds) noexcept
  135. {
  136. m_config.expiration_in_seconds = expirationInSeconds;
  137. }
  138. const std::shared_ptr<ICredentialsProvider> &AwsSigningConfig::GetCredentialsProvider() const noexcept
  139. {
  140. return m_credentialsProvider;
  141. }
  142. void AwsSigningConfig::SetCredentialsProvider(
  143. const std::shared_ptr<ICredentialsProvider> &credsProvider) noexcept
  144. {
  145. m_credentialsProvider = credsProvider;
  146. m_config.credentials_provider = m_credentialsProvider->GetUnderlyingHandle();
  147. }
  148. const std::shared_ptr<Credentials> &AwsSigningConfig::GetCredentials() const noexcept
  149. {
  150. return m_credentials;
  151. }
  152. void AwsSigningConfig::SetCredentials(const std::shared_ptr<Credentials> &credentials) noexcept
  153. {
  154. m_credentials = credentials;
  155. m_config.credentials = m_credentials->GetUnderlyingHandle();
  156. }
  157. const struct aws_signing_config_aws *AwsSigningConfig::GetUnderlyingHandle() const noexcept
  158. {
  159. return &m_config;
  160. }
  161. /////////////////////////////////////////////////////////////////////////////////////////////
  162. Sigv4HttpRequestSigner::Sigv4HttpRequestSigner(Aws::Crt::Allocator *allocator)
  163. : IHttpRequestSigner(), m_allocator(allocator)
  164. {
  165. }
  166. struct HttpSignerCallbackData
  167. {
  168. HttpSignerCallbackData() : Alloc(nullptr) {}
  169. Allocator *Alloc;
  170. ScopedResource<struct aws_signable> Signable;
  171. OnHttpRequestSigningComplete OnRequestSigningComplete;
  172. std::shared_ptr<Http::HttpRequest> Request;
  173. };
  174. static void s_http_signing_complete_fn(struct aws_signing_result *result, int errorCode, void *userdata)
  175. {
  176. auto cbData = reinterpret_cast<HttpSignerCallbackData *>(userdata);
  177. if (errorCode == AWS_OP_SUCCESS)
  178. {
  179. aws_apply_signing_result_to_http_request(
  180. cbData->Request->GetUnderlyingMessage(), cbData->Alloc, result);
  181. }
  182. cbData->OnRequestSigningComplete(cbData->Request, errorCode);
  183. Crt::Delete(cbData, cbData->Alloc);
  184. }
  185. bool Sigv4HttpRequestSigner::SignRequest(
  186. const std::shared_ptr<Aws::Crt::Http::HttpRequest> &request,
  187. const ISigningConfig &config,
  188. const OnHttpRequestSigningComplete &completionCallback)
  189. {
  190. if (config.GetType() != SigningConfigType::Aws)
  191. {
  192. aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
  193. return false;
  194. }
  195. auto awsSigningConfig = static_cast<const AwsSigningConfig *>(&config);
  196. if (!awsSigningConfig->GetCredentialsProvider() && !awsSigningConfig->GetCredentials())
  197. {
  198. aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
  199. return false;
  200. }
  201. auto signerCallbackData = Crt::New<HttpSignerCallbackData>(m_allocator);
  202. if (!signerCallbackData)
  203. {
  204. return false;
  205. }
  206. signerCallbackData->Alloc = m_allocator;
  207. signerCallbackData->OnRequestSigningComplete = completionCallback;
  208. signerCallbackData->Request = request;
  209. signerCallbackData->Signable = ScopedResource<struct aws_signable>(
  210. aws_signable_new_http_request(m_allocator, request->GetUnderlyingMessage()), aws_signable_destroy);
  211. return aws_sign_request_aws(
  212. m_allocator,
  213. signerCallbackData->Signable.get(),
  214. (aws_signing_config_base *)awsSigningConfig->GetUnderlyingHandle(),
  215. s_http_signing_complete_fn,
  216. signerCallbackData) == AWS_OP_SUCCESS;
  217. }
  218. } // namespace Auth
  219. } // namespace Crt
  220. } // namespace Aws